흔히들 호이스팅이 무엇인가요? 라는 질문에 변수와 함수 선언이 해당 스코프의 상단으로 이동하는 것이라고 답한다.
하지만 실제로 호이스팅(Hoisting) 은 변수와 함수 선언이 해당 스코프의 상단으로 "끌어올려지는" 것처럼 동작하는 것이다.
이때 선언 부분만 끌어올려지는 것처럼 동작하고, 초기화나 할당은 해당 줄에 있는 것처럼 동작한다.
즉, 코드의 실행 순서와는 무관하게 변수와 함수 선언이 스코프의 맨 위로 이동되어 마치 끌어올려진 것처럼 동작해 스코프 내에서 사용할 수 있게 해준다.
호이스팅은 자바스크립트에서 중요한 동작 메커니즘 중 하나로 코드 실행 순서와 변수 및 함수의 선언과 초기화를 이해하는 데 큰 도움이 된다.
자바스크립트에서 변수를 선언할 때 var, let, const 키워드를 사용한다.
var는 호이스팅되지만, let과 const는 호이스팅이 발생하지 않는다는 오해가 종종 있다.
예를 들어, 아래와 같은 코드를 보자.
console.log(x); // undefined
var x = 2;
console.log(x); // 2
이 경우 var x = 2; 부분은 호이스팅 단계에서 변수가 선언 및 초기화된다.
하지만 선언 코드 (var x)는 끌어올려지는 것 같이 동작하나, 대입되는 코드(x = 2)는 끌어올려지지 않아 변수의 초기값은 undefined로 출력된다.
반면, let, const의 경우는 다르다.
console.log(b); //Uncaught ReferenceError: Cannot access 'y' before initialization
let y = 1;
console.log(y);
Uncaught ReferenceError: Cannot access 'y' before initialization
이렇게 let, const로 선언된 변수들은 호이스팅 단계에서 선언되지만 초기화는 이루어지지 않는다.
변수가 선언된 위치에서 초기화 구문까지의 구간을 TDZ(Temporal Dead Zone, TDZ) 라 부른다. 이 구간에서 변수에 접근하게 되면 ReferenceError가 발생한다.
정확히는 const, let이 호이스팅이 발생하지 않는 것이 아니다.
선언문을 통해 모든 식별자(변수, 함수, 클래스 등)는 호이스팅된다. 그러나 var과 다르게 초기화되기 전까지 TDZ에 머물러있기 때문에 호이스팅이 발생하지 않는 것처럼 보이며 참조가 불가능하다.
호이스팅은 선언을 상단으로 끌어올려지는 것 같은 개념이지만 초기화나 할당은 영향을 받지 않는다.
var, let, const의 동작 방식에 따라 변수의 초기화 시점이나 TDZ 존재 여부가 다르다. 이를 통해 변수와 함수의 동작을 예측하고 코드를 더 효율적으로 작성할 수 있게 된다.
https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
https://ingg.dev/hoisting/