Hoisting
함수나 변수, 클래스, 또는 import 구문을 Interpreter가 소스 코드 실행 전, 이들의 선언을 해당 영역(ex. Global, Funtion, Block Scope(ES6+) 등)의 최상단으로 옮기는 과정을 말한다. 따라서, 해당 영역의 시작 부분에서 선언된 것처럼 동작할 수 있다. 가령,
var
로 선언된 변수가 해당 영역의 최상단으로 옮겨지는 것처럼 말이다.
종류
- Value Hoisting (할당)
- Declaration Hoisting (선언)
- ES6+
변수가 할당되기 이전에, ReferenceError
를 발생시키지 않고 해당 변수를 사용할 수 있다. 하지만 그 값은 Hoisting 되지 않기 때문에 항상 undefined
이다.
console.log(foo); // Output: undefined
var foo = 'This is hoisted.';
이는 아래의 코드와 동일하다.
var foo;
console.log(foo); // Output: undefined
foo = 'This is hoisted.';
함수가 호출되기 이전에 이미 선언되기 떄문에 다음과 같이 사용할 수 있다.
console.log(bar()); // Output: 'This is hoisted too!'
function bar() {
return 'This is hoisted too!';
}
ES6+에서 let
또는 const
(Block Scope), class
로부터 선언된 변수는 Hoisting 된 것처럼 해석되지만, ReferenceError
를 발생시키며 사용할 수 없도록 돼 있다. 이는 Temporal Dead Zone에 의해 금지된다.
const x = 1;
{
console.log(x); // ReferenceError
const x = 2;
}
위와 같이 Scope가 다른 경우, const x = 2;
라인에서 변수 x
가 Hoisting 되지 않았다면, const x = 1;
로부터 값을 읽어버리기 때문에 이를 방지할 수 있다.
warning
아래의 경우는 Hoisting과 무관하다.
{
var x = 1;
}
console.log(x) // Output: 1
위의 경우, var
는 Block Scope를 따르지 않고 전역으로 선언되었기 때문에 이는 Hoisting과는 무관하다.