
ES6 이후로 변수 식별자로 var, let, const를 사용하게 되었다.
특히 var는 레거시한 키워드가 되버렸고 현재는 let과 const를 주로 사용하는데
왜 var가 레거시가 되었는지 생각해보면 호이스팅의 문제라고 생각한다.
여기서 궁금한건 변수의 호이스팅인데,
var는 호이스팅을 일으키지만 let, const는 호이스팅이 일어나지 않는 것이라 생각하고 있었다.
허나 이는 잘못된 생각이였고 변수의 선언은 호이스팅이 일어나고 뿐만 아니라 키워드를 사용해서 선언하는 모든 식별자(변수, 함수, 클래스 등)은 호이스팅이 된다는 것이다.
우선 호이스팅이 무엇인지 알아보자.
🔎 호이스팅 : 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징
console.log(score); // undefined var score; //변수 선언
예시는 var로 설명했지만 let, const 또한 호이스팅은 일어난다 다만 var의 경우 에러없이 undefined로 표시되지만 let과 const는 ReferenceError를 띄우게 된다.
console.log(score); // ReferenceError: Cannot access 'score' before initialization
let score;
위 같은 상황(호이스팅)이 발생하는 이유는 변수 선언과 할당의 실행 시점이 다르기 때문인데
자바스크립트 엔진은 소스코드를 순차적으로 실행되는 런타임 이전에 선언문이 실행되기 때문이고
할당문은 런타임에 실행된다.
보통 변수의 선언과 할당을 한번에 쓰고 있었기 때문에
let score = 100; // score 선언과 100 할당
선언과 할당의 실행시점을 고려하지 않았었다.
하지만 자바스크립트 엔진은 소스코드를 순차적으로 실행되는 런타임 이전에 모든 선언문을 실행시킨다는 것이다.
그러므로 var, let, const는 모두 호이스팅이 발생하게 되는 것이다
근데 여기서 왜 var는 undefined이고 let과 const는 ReferenceError가 발생하는 것일까?
그 이유는 var는 선언과 즉시 undefined로 초기화를 한다는 것이다.
즉, 선언과 즉시 재할당을 하게되는 것이고 let과 const는 호이스팅은 되었지만 초기화가 이루어지지 않았기 때문에 ReferenceError가 발생하게 되는 것이다.
1. 변수를 사용하기 위해선 var, let, const 식별자를 통해 선언과 할당으로 이루어진다.
2. 선언은 메모리 공간을 확보하고 그 공간을 식별자로 구별한다.
3. 할당은 확보된 메모리 공간에 값을 초기화 시킨다.
4. var의 경우 선언과 동시에 undefined로 초기화가 이루어진다.
5. let, const는 선언을 했을 때 초기화가 이루어지지 않고 할당을 통해 초기화가 된다.
*const는 선언만 할 순 없다 (선언과 동시에 할당 필요)
즉, 'var는 호이스팅을 일으키고 let, const는 호이스팅을 일으키지 않는다'가 아니라 호이스팅 자체는 자바스크립트 엔진의 고유 특징이고 var를 사용 시 의도와 다르게 undefined로 덮어 쓰일 수 있고 디버깅을 찾기 어렵기 때문에 ES6 이후로 let, const 사용이 권장된다.