hoist : 끌어올리다.
함수 혹은 변수에서의 호이스팅은 할당부까지 전부 상단으로 호이스팅 하는 것이 아닌 선언부를 호이스팅한다.
var
의 life cycle을 보면 선언과 초기화가 동시에 이루어지는 것을 알 수 있다.
그렇기에 두 부분을 호이스팅 한다.
console.log(v);
var v = 2;
위의 예제는 2를 출력하는 것이 아니고, 선언과 초기화가 이루어진 v 즉 undefined
를 출력한다.
하지만 let
은 다르다.
console.log(a);
let a = 2;
위의 예제는 ReferenceError: a is not defined. 정의되어 있지 않다며 에러가 뜬다.
밑의 글을 보자.
일시적 사각지대
let
, const
, class 구문
, constructor() 내부의 super()
, 함수 기본 매개변수
에 적용
var
, 함수
에는 적용 X
TDZ: 함수의 선언 및 초기화 이전 과정에 해당.
대강 이렇긴 한데 let
이 호이스팅이 된다는게 사실 이해가 안 갔다.
console.log(a);
let a = 2;
위의 예시는 ReferenceError: a is not defined. 호이스팅이 되었다면 정상적으로 2를 출력했을 텐데, a가 정의되지 않았다며 에러를 출력했기 때문이다.
그래서 찾아봤다.
이 예시가 내 이해를 도왔다.
let foo = 1;
{
console.log(foo);
let foo = 2;
}
블럭스코프 내에 let
이 호이스팅이 되지 않았다면, foo는 전역변수이기 때문에 콘솔에 1이 출력되었어야 했지만
Uncaught ReferenceError: Cannot access 'foo' before initialization at <anonymous>:3:14
(anonymous) @ VM43:3
결과는 ReferenceError가 떴다. 그렇다 블럭스코프 내에 foo가 호이스팅 되어 초기화 이전에 foo는 접근할 수 없다는 에러가 뜬 것이다.
이 글에서 내 결론은 이렇다.
var
는 선언과 초기화가 동시에 이루어지고, 그렇기에 호이스팅 또한 초기화 된 상태로 호이스팅 된다.
하지만 let
은 선언과 초기화가 따로 이루어지고, 할당된 변수에 대한 호이스팅은 선언 그 이후 TDZ상태로 호이스팅 되어 호이스팅 된 let
에 접근하게 되면 Reference Error가 뜬다.