선언단계에서는 변수를 실행컨텍스트의 변수 객체에 등록한다.
초기화 단계에서는 컨텍스트에 등록된 변수 객체를 메모리에 할당하고, 이단계에서 변수는 undefined로 초기화된다.
할당단계에서는 undefined로 초기화된 변수에 값을 할당한다.
var는 선언하기 전에 사용 가능하다. 아래의 코드를 살펴보면var color = "red"; console.log(color);
var의 선언하고 그 값을 할당했다. 그리고 코드를 실행하면 당연히red가 출력된다.
하지만 아래 코드처럼 변수의 선언과 할당을 밑으로 내리고 실행을 하게 되면console.log(color); var color = "red"; //undefined
undefined가 출력된다.
이유를 살펴보면 호이스팅이 실행될 때var는 코드 유효범위(스코프) 최상단으로 이동한다.(실제로 이동하는건 아니다)var color; console.log(color); //undefined color = "red";
var경우 선언과 초기화 과정이 한번에 이루어진다. 그렇기 때문에var color를 선언하고console.log를 하면undefined가 출력된다.
console.log(color); // ReferenceError: foo is not defined // 스코프의 선두에서 선언 단계가 실행된다. // 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않았다. // 따라서 변수 선언문 이전에 변수를 참조할 수 없다.let color; // 변수 선언문에서 초기화 단계가 실행된다. console.log(color); // undefinedcolor = 'red'; // 할당문에서 할당 단계가 실행된다. console.log(color); // red
위 과정을 살펴보면 마치 호이스팅이 일어나지 않는것 처럼 보인다.
하지만 아래 예제를 살펴보면 let 키워드에서도 호이스팅이 일어난다는 것을 알 수있다.
let color = 'red'; // 전역 변수 { console.log(color); // ReferenceError: foo is not defined let color = 'blue'; // 지역 변수 }
- 호이스팅은 스코프 단위로 일어난다.
let은 블록스코프이기 때문에{ }안에 있는let이 호이스팅을 일으켜 참조에러가 발생하게 된다. 만약 호이스팅이 정상적으로 일어나지 않는다면 전역 변수 값이 출력이되는데 그렇지 않다.