자바스크립트 호이스팅에 대해 정리한다.
호이스팅은 무엇인가?
MDN 문서에 따르면, 호이스팅은 인터프리터가
코드를 실행하기 전에 함수, 변수, 클래스 또는 임포트(import)의선언문을해당 범위의 맨 위로 이동시키는과정을 말한다.
아래 코드를 예시로 보면
1
2
3
console.log(x); // undefined
var x = 1;
console.log(x) 가 실행되는 시점은 변수 x가 선언되기 전이기 때문에 참조 에러가 발생할 것으로 보이지만 실제로는 undefined 가 출력된다.
코드를 실행하기 전 선언문을 해당 범위의 맨 위로 이동시키는 과정 이라는 정의를 보았을 때 그 이유는 변수 선언은 코드가 실행되는 시점(런타임)이 아닌 그 이전에 코드의 위로 끌어 올려지기 때문에 변수 선언의 위치에 상관없이 변수를 참조할 수 있다.
var, let, const
각 키워드 별 특징은 아래 표와 같다.
| 키워드 | 범위 | 호이스팅 | 변경 가능 여부 | 중복 선언 가능 여부 |
|---|---|---|---|---|
| var | 함수 스코프 | 호이스팅+초기화(undefined) | 가능 | 가능 |
| let | 블록 스코프 | 호이스팅 | 가능 | 불가능 |
| const | 블록 스코프 | 호이스팅 | 불가능 | 불가능 |
1
2
3
4
5
console.log(x); // ReferenceError
console.log(y); // ReferenceError
let x = 1;
const y = 2;
let 과 const 의 경우 위 코드처럼 선언 이전에 참조하면 참조 에러가 발생해 호이스팅이 일어나지 않는 것과 같이 보이지만 이는 런타임 이전에 선언단계 와 초기화 단계 가 한번에 되는 var 와 달리 let 과 const 의 경우 선언단계 와 초기화 단계 가 분리되어 런타임 이전에 선언단계 가 실행되고 초기화 단계 는 선언문에 도달했을 때 진행되기 때문에 선언 이전에 참조하면 에러가 발생한다.
이렇게 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 일시적 사각지대(Temporal Dead Zone:TDZ) 라고 부른다
함수 호이스팅
함수 역시 호이스팅이 일어나지만
함수 선언문과함수 표현식두 방식의 동작은 조금 다르다.
함수 선언문 의 경우 런타임 이전에 함수 객체가 먼저 생성되고 자바스크립트 엔진은 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 생성된 객체를 할당한다. 따라서 런타임에는 이미 함수 객체가 생성되어 있고 함수 이름과 동일한 식별자까지 할당이 완료된 상태이기 때문에 함수 선언문 이전에 함수를 참조할 수 있고 호출 역시도 가능하다.
함수 표현식 의 경우 함수 리터럴이 변수에 할당되는 형태이기 때문에 함수 호이스팅 이 아닌 변수 호이스팅 이 발생하므로 선언 이전에 호출 시 타입에러가 발생한다.
클래스 호이스팅
클래스는
let,const키워드로 선언한 변수처럼 호이스팅 된다.
1
2
3
4
console.log(Person);
// ReferenceError: Cannot access 'Person' before initialization
// 클래스 선언문
class Person {}