호이스팅이란 변수, 함수, 클래스, impot 선언이 해당 범위의 맨 위로 이동되는 자바스크립트 매커니즘입니다.
console.log(a); // undefined
var a = 'hello';
위와 같이 변수 a
를 참조하는 코드가 변수의 선언보다 앞에 있을 때, 해당 코드가 참조 에러(reference error)를 발생시킬 것으로 보이지만 에러가 발생하지 않고 console.log(a)
에서는 undefined
가 출력됩니다.
그 이유는 자바스크립트 엔진에서 변수를 선언할 때 런타임(runtime) 환경이 아니라
그 이전 단계에서 먼저 실행되어 선언 단계와 초기화 단계를 거치기 때문입니다.
console.log(a);
var a = 'hello';
즉 위와 같은 코드를 실행할 때, 자바스크립트 엔진은 변수 선언을 포함한 모든 선언문(변수, 함수, 등)을 찾아 아래와 같이 먼저 실행한 후, 해당 선언들을 제외하고 그 이외의 소스 코드들을 순차적으로 실행합니다.
var a;
console.log(a); // undefined
a = 'hello';
var로 선언된 변수 a
의 스코프는 전역적(global scope)이기 때문에, 스코프 내에서 맨 위로 올려져 값은 undefined
로 초기화 됩니다. 그래서 console.log(a)
의 결과값으로 undefined
가 출력됩니다.
let으로 변수를 선언했을 경우에도 var와 같이 호이스팅 현상이 일어나지만, undefined로 값이 초기화되지 않습니다. 그렇기 때문에 let으로 선언한 변수를 참조하는 코드가 변수 선언보다 앞에 위치한다면 참조 오류(Reference Error)가 발생합니다.
console.log(b);
let b = 'banana';
let b;
console.log(b); // ReferenceError: b is not defined
b = 'banana';
var, let과 마찬가지로 const 선언도 호이스팅 현상이 일어납니다. 그러나 초기화되지는 않습니다.
const는 선언과 동시에 값을 할당해야 하므로 선언만 단독으로 사용할 수 없습니다.
console.log(c); // ReferenceError: c is not defined
const c = 'cherry';
const c; // // SyntaxError: Missing initializer in const declaration
console.log(c);
c = 'ccm';
var
, let
, const
로 선언된 변수와 상수는 모두 해당 범위 안에서 호이스팅 됩니다.var
의 경우 호이스팅되며 변수값이 초기화되어 undefined로 자동 할당됩니다.let
과 const
는 호이스팅 되지만 변수/상수에 값이 할당되지 않기 때문에 값을 할당하기 이전에 해당 변수를 참조하는 코드가 실행된다면 참조 에러(reference error)가 발생합니다.