선언단계에서는 변수를 실행컨텍스트의 변수 객체에 등록한다.
초기화 단계에서는 컨텍스트에 등록된 변수 객체를 메모리에 할당하고, 이단계에서 변수는 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); // undefined
color = 'red'; // 할당문에서 할당 단계가 실행된다. console.log(color); // red
위 과정을 살펴보면 마치 호이스팅이 일어나지 않는것 처럼 보인다.
하지만 아래 예제를 살펴보면 let 키워드에서도 호이스팅이 일어난다는 것을 알 수있다.
let color = 'red'; // 전역 변수 { console.log(color); // ReferenceError: foo is not defined let color = 'blue'; // 지역 변수 }
- 호이스팅은 스코프 단위로 일어난다.
let
은 블록스코프이기 때문에{ }
안에 있는let
이 호이스팅을 일으켜 참조에러가 발생하게 된다. 만약 호이스팅이 정상적으로 일어나지 않는다면 전역 변수 값이 출력이되는데 그렇지 않다.