변수 선언의 실행 시점과 변수 호이스팅
값의 할당
값의 재할당
마무리
내 생각
오늘은 변수 선언의 실행 시점과 호이스팅, 값의 할당, 재할당을 다뤄볼겁니다.😀
console.log(num1);
var num1;
위와 같은 예시코드가 있습니다. 위의 conloe.log(num1)에서는 어떤 값을 출력할까요?
javascript는 인터프리터 언어라 위에서부터 실행되고 console.log(num1);를 하는 시점에는 아직 num1이라는 변수를 선언하지 않았으니 참조 에러(ReferenceError)가 날 것처럼 보입니다.
하지만 결과는??
undefined가 나옵니다..!!
그 이유는 변수 선언이 소스코드가 한 줄씩 순차적으로 실행되는 시점, 즉 런타임(runtime)이 아니라 그 이전 단계(소스코드 평가과정)에서 먼저 실행되기 때문입니다.
💡 자바스크립트의 실행 과정
소스코드의 평가
- 소스코드를 실행하기 위한 준비 단계로 자바스크립트 엔진은 변수 선언을 포함한모든 선언문
(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 런타임 시 실행되는 실행컨텍스트 내의 스코프에 등록합니다.소스코드의 실행(runtime)
- 소스코드의 평과 과정이 끝나면 변수 선언을 포함한 모든선언문을 제외한 소스코드
를 한 줄씩 순차적으로 실행합니다.
위 예제처럼 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅(variable hoisting)
이라고 합니다.
변수에 값을 할당(assignment)할 때는 할당 연산자 =를 사용합니다. 할당 연산자는 우변의 값을 좌변의 변수에 할당합니다.
var num1;
num1 = 50;
변수 선언과 값의 할당을 하나의 문(statement)으로 단축 표현할 수도 있습니다.
var num1 = 50;
위 2개의 예제는 정확히 동일하게 작동합니다.
💡 자바스크립트 엔진의 특징
- 자바스크립트 엔진은 변수 선언과 값의 할당을 하나의 문으로 단축표현 하더라도
변수 선언과 값의 할당을 2개의 문으로 나누어 각각 실행합니다.
// 예제 코드 1번
console.log(num1); // undefined
var num1; // 1 변수 선언
num1 = 50; // 2 값의 할당
console.log(num1); // 50
// 예제 코드 2번
console.log(num1); // undefined
var score = 50; // 변수 선언 및 할당
console.log(num1); // 50
예제 코드 1번에서 변수 선언(1)은 런타임 이전에 먼저 실행되고 값의 할당(2)은 런타임에 실행됩니다.
따라서 num1 변수에 값을 할당하는 시점(2)은 이미 변수 선언이 완료된 상태이고,
자바스크립트 엔진에 의해 이미 undefined로 초기화되어 있습니다.
따라서 num1 변수에 값을 할당하면 num1 변수의 값은 undefined에서 새롭게 할당한 숫자 값 50으로 변경(재할당)됩니다.
예제 코드 2번은 선언과 할당을 나누어 진행하므로 예제 코드 1번과 동일한 결과가 나옴을 확인할 수 있습니다.
💡 !! 여기서 주의할 점 !!
- 여기서 주의할 점은 변수에 값을 할당할 때는
이전 값 undefined가 저장되어 있던 메모리 공간을 지우고
기존의 그 메모리 공간에 할당 값 50을 저장하는 것이 아니라
새로운 메모리 공간을 확보하고 그곳에 값 50을 저장한다는 것입니다.
console.log(num1);
num1 = 80;
var num1;
console.log(num1);
이번엔 재할당을 해봅시다. 재할당이란 말 그대로 이미 값이 할당되되 있는 변수에 새로운 값을 또 다시 할당하는 것을 말합니다.
var num1 = 50; // 변수 선언 및 할당
num1 = 70; // 값 재할당
var키워드로 선언한 변수는 값을 재할당할 수 있습니다.
var키워드로 선언한 변수는 선언과 동시에 undefined로 초기화되기 때문에
엄밀히 말하면 변수에 처음으로 값을 할당하는 것도 사실은 재할당입니다.
변수에 값을 재할당하면 num1
변수의 값은 이전 값 50에서 재할당한 값 70으로 변경됩니다.
처음 값을 할당했을 때와 마찬가지로 이전 값 50이 저장되어 있던 공간의 값을 지우고 그 메모리 공간에 재할당 값 70을 새롭게 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 그 메모리 공간에 숫자 값 70을 저장합니다.
위의 코드가 모두 실행되고 난 후의 num1
변수의 값은 70입니다.
num1
변수에 undefined -> 50 -> 70 순으로 값을 할당했습니다.
각각의 값을 갖고 있는 메모리 주소는 3경우 모두 다릅니다.
현재 값이 아닌 이전 값(undefined, 50)들은 더 이상 필요하지 않는 값입니다.
이러한 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동으로 해제됩니다.
💡 단, 메모리에서 언제 해제될지는 예측할 수 없습니다.
오늘은 변수 선언의 실행 시점과 변수 호이스팅, 값의 할당, 값의 재할당에 대해 다뤄봤습니다.
오늘 다룬 내용 중 중요한 거는
1. 자바스크립트 실행 과정(소스코드 평가(선언문) -> 소스코드 실행)
2. 할당 및 재할당은 기존의 공간을 재활용하는 것이 아닌 새로운 메모리 공간에 한다.
3. 자바스크립트 엔진은 단축표현을 하더라도 변수 선언과 값의 할당을
2개의 문으로 나눠서 각각 실행한다.
1. const는 재할당이 불가능하고 선언과 할당을 동시에 해줘야 하는데 어느 타이밍에서 실행될까?