Javascript 에서 호이스팅이란 변수나 함수의 선언이 끌어올려지는 것처럼 보이는 것을 말한다. (실제로 끌어올려지지는 않는다.)
Javascript 는 문을 실행하는 런타임 이전에, 코드 평가 과정을 거치면서 코드를 실행하기 위한 준비를 한다.
이때 자바스크립트 엔진은 모든 선언문을 찾아서 먼저 실행한다. 이 때문에 선언문이 끌어올려져서 실행되는 것처럼 보이는 것이다.
console.log(a); // undefined
var a;
a = 10;
console.log(a); // 10;
위 예제에서 a를 선언하기 이전에 값을 확인해보면 undefined 인 것을 확인할 수 있다.
var
로 선언된 변수는 선언과 동시에 undefined 로 초기화 되기 때문이다.
하지만 변수를 실행하기도 전에 참조할 수 있는 것은 직관적으로 자연스럽지도 않고, 문제를 일으킬 여지가 상당히 많아보인다.
ES6 이후 등장한 let
과 const
는 선언과 초기화를 나눠서 실행함으로써
호이스팅이 되지 않는 것처럼 보이게한다.
console.log(b); // Uncaught ReferenceError: b is not defined
let b;
console.log(b); // undefined;
b = 20;
console.log(b); // 20;
위 예제에서 let
으로 선언한 변수 b 또한 호이스팅 되었지만, 선언만 되고 초기화는 되지 않았기 때문에 정의되지 않았다는 에러메세지가 뜬다.
선언문을 만났을 때 비로소 undefined로 초기화를 하고, 이후 재할당을 한 뒤 다시 값을 확인해보면 재할당한 값으로 바뀐 것을 확인할 수 있다.
console.log(c); // Uncaught ReferenceError: c is not defined
const c = 30;
console.log(c); // 30;
const
로 선언한 변수도 마찬가지로 선언과 초기화가 나눠서 일어난다.
다만 const
로 선언된 변수는 재할당할 수 없기 때문에 코드를 작성할 때는 선언과 동시에 할당을 해주어야한다.
let
과 마찬가지로 실제로 변수선언은 호이스팅되어서 런타임 이전에 이루어지지만, 초기화는 런타임에서 const
선언문을 실행하는 시점에 이루어진다.
let
으로 선언한 변수는 (코드 작성시 선언과 함께 초기화하지 않은 경우) undefined로 초기화 될 수도 있지만 const
으로 선언한 변수는 코드 작성시 선언과 초기화를 반드시 같이해주어야 한다는 점이 다르다.
Javascript는 런타임 이전에 코드평가를 진행하면서 선언문을 미리 실행한다.
ES6 이전에는 변수가 선언됨과 동시에 undefined
로 초기화 되었기 때문에 변수선언문 이전에 참조할 수 있었다.