호이스팅(Hoisting)은 Javascript의 기본 동작 방식으로, 변수 선언과 함수 선언이 실제 코드 실행 전에 해당 스코프의 최상단으로 끌어올려지는 것처럼 동작하는 현상이다.
실제로 코드가 이동하는 건 아니고, 자바스크립트의 실행 컨텍스트가 변수를 메모리 공간에 미리 할당하기 때문에 발생하는 현상이다.
그러나 변수의 초기화는 호이스팅되지 않고, 선언만 호이스팅된다.
변수 호이스팅은 var
, let
, const
로 선언된 변수에서 다르게 나타난다.
var
변수의 호이스팅console.log(a); // undefined
var a = 5;
console.log(a); // 5
위의 코드에서 var a = 5;
는 var a;
와 a = 5;
로 분리된다.
var a;
는 최상단으로 호이스팅되고 a = 5;
는 원래 위치에 남아있게 된다.
따라서 첫 번째 console.log(a);
는 undefined
를 출력한다.
var a;
console.log(a); // undefined
a = 5;
console.log(a); // 5
let
과 const
의 호이스팅let
과 const
로 선언된 변수도 호이스팅되지만, var
와는 달리 초기화 전에 접근하려 하면 ReferenceError
가 발생한다. 이를 "일시적 사각지대(Temporal Dead Zone, TDZ)"라고 한다.
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
함수 선언문으로 정의된 함수는 코드의 최상단으로 완전히 끌어올려지기 때문에, 함수 선언 전에 해당 함수를 호출할 수 있다.
console.log(myFunc()); // "Hello, World!"
function myFunc() {
return "Hello, World!";
}
위의 코드에서 function myFunc() { ... }
전체가 호이스팅되기 때문에 console.log(myFunc());
가 정상적으로 실행된다.
function myFunc() {
return "Hello, World!";
}
console.log(myFunc()); // "Hello, World!"
하지만 함수 표현식(var
, let
, const
에 함수 리터럴을 할당하는 경우)은 변수 호이스팅 규칙을 따른다.
console.log(myFunc()); // TypeError: myFunc is not a function
var myFunc = function () {
return "Hello, World!";
}
위 코드에서 var myFunc
가 호이스팅 되었지만, 초기화 전에 함수 호출이 시도되었기 때문에 undefined
가 function
으로 호출되어 TypeError
가 발생한다.
일시적 사각지대는 let
과 const
변수에서 발생하며, 변수 선언이 실제로 이루어지기 전까지 그 변수에 접근할 수 없는 구간을 의미한다.
{
// TDZ starts at beginning of scope
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 30; // End of TDZ
console.log(x); // 30
}
TDZ
는 코드가 작성된 위치가 아닌 실행 순서에 따라 영역이 달라진다.
// TDZ starts at beginning of scope
function printValue() {
console.log(value); // ReferenceError: Cannot access 'value' before initialization
}
printValue();
let value = 10; // End of TDZ
printValue(); // 10
첫번째 printValue
함수를 호출했을 때, value
변수는 아직 선언되지 않았다. 자바스크립트 엔진은 이 변수가 TDZ
에 있다고 판단하고 ReferenceError
를 발생시킨다.
let value = 10
을 선언하면서 TDZ가 해제되고, 두번째 printValue
함수를 호출했을 때 정상적으로 10
이 출력된다.
호잇!스팅