호이스팅
인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. 그래서 선언하기 전에 변수를 참조할 수 있게 합니다. 이렇게 할 수 있는 이유는 자바스크립트 엔진은 먼저 전체 코드를 스캔하면서 변수같은 정보를 실행 컨텍스트에 미리 기록해두기 때문입니다.
선언 라인 전에도 에러가 나지 않고 변수를 참조할 수 있는 현상을 선언문이 마치 최상단에 끌어 올려진듯 하다고 해서 호이스팅 현상이라고 합니다.
// 변수 호이스팅console.log(abc); // undefinedvar abc = "abc";console.log(abc); // abc// 함수 호이스팅console.log(func);// function func() {// console.log('called func');// }function func() {console.log("called func");}
기본 규칙
변수나 함수는 선언과 초기화를 해주어야만 값의 참조 및 할당이 가능합니다.
호이스팅 규칙
- 선언된 함수는 상단에서
참조,호출이 가능합니다. - 선언된 var는 상단에서
참조,할당이 가능합니다. - 선언된 let, const는 상단에서
참조,할당이 불가능합니다.
변수 호이스팅
변수는 프로그램 내에서 크게 세 가지 단계를 거칩니다. (이 단계는 실행 컨텍스트의 Environment record 공간에서 이루어집니다)
- 선언 : 변수 객체가 변수에 대한 식별자들을 수집합니다.
- 초기화 : 식별자에 메모리를 할당하고 undefined 상태를 부여합니다.
- 할당 : 변수 안에 직접 값을 넘겨줍니다.
변수를 어떻게 선언했는지에 따라 선언, 초기화 시점이 달라집니다.
var
- 호이스팅이 발생하면, 선언과 초기화(undefined)가 동시에 이루어집니다.
let, const
- 호이스팅이 발생하면, 선언만 이루어지고 실행 시점에서 실질적인 선언부를 만날 때 까지 초기화는 이루어지지 않습니다.
// 이 구간은// abc를 참조할 수 없다!// console.log(abc); Uncaught ReferenceError: Cannot access 'abc' before initialization// TDZ(Temporal Dead Zone)이라고 한다let abc = "abc";cosnole.log(abc);
let, const가 동작하는 과정에서 스코프의 진입 지점과 해당 식별자의 실질적 선언부를 일시적 사각지대, TDZ(Temporal Dead Zone)이라고 합니다. 여기서 변수는 존재하지만, 초기화가 되어있지 않습니다.
함수 호이스팅
함수 표현식
- 변수 호이스팅과 똑같이 동작합니다.
함수 선언문
- 식별자가 변수 객체에 수집될 때 부가적으로 해당 함수 참조에 대한 초기화 까지 자동으로 이루어집니다. 그래서 선언된 함수는 상단에서 참조, 호출이 가능합니다.