나만보는개발공부블로그

Hoisting 본문

Javascript&Typescript

Hoisting

alexrider94 2021. 3. 4. 00:22

호이스팅이란?

- 함수 안에 있는 선언들을 모두 끌어 올려서 해당 함수 유효 범위의 최상단에 선언하는 것

- var 선언문이나 function 선언문 등을 해당 스코프의 선두로 옮긴 것처럼 동작하는 특성

 

 

let 키워드로 선언된 변수를 선언문 이전에 참조하면 참조 에러가 발생하는데 스코프의 시작에서 변수의 선언까지 일시적 사각지대에 빠지기 때문이다.

* 일시적사각지대=TDZ(Temporal Dead Zone) : 초기화되지 않은 변수가 있는 곳. 변수가 초기화 되는 순간 TDZ에서 나오게 되며 사용할 수 있게 되는 것.

 

변수 생성 과 호이스팅이 이루어지는 과정

변수는 3단계에 걸쳐서 생성된다.

1. 선언 단계(Declaration Phase) : 변수를 실행 컨텍스트의 변수 객체에 등록한다. 변수 객체는 스코프가 참조하는 대상이 된다.

2. 초기화 단계(Initialization Phase) : 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다. 이 단계에서 변수는 undefined로 초기화 된다.

3. 할당 단계(Assignment Phase) : undefined로 초기화된 변수에 실제 값을 할당한다.

 

 

console.log(foo); // undefined
var foo;

console.log(bar); // Error: Uncaught ReferenceError: bar is not defined
let bar;

var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다. 스코프에 변수를 등록하고 메모리에 변수를 공간을 확보한 후, undefiend로 초기화한다. 따라서 변수 선언문 이전에 변수에 접근하여도 스코프에 변수가 존재하기 때문에 undefined를 반환할뿐 에러가 발생하지 않는다. 이후 변수 할당문에 도달하면 값이 할당되게 된다. 이러한 현상을 변수 호이스팅이라 한다.

 

let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 스코프에 변수를 등록하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어진다. 그래서 초기화 이전에 변수에 접근하려고 하면 참조 에러가 발생한다. (아직 메모리에 공간이 확보되지 않음) 그래서 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 일시적 사각지대(TDZ)라고 부른다.

 

 

ES6에서는 호이스팅이 발생하지 않는 것과 차이가 없어보이지만 아래 코드에서 보면 그렇지 않다.

let an = 1; // 전역 변수
{
 console.log(an); // ReferenceError : an is not defined
 let an = 2; // 지역 변수
}

위의 코드를 보면 전역 변수의 값이 출력되는것 처럼 보이지만 참조 에러가 발생한다. ES6의 let으로 선언된 변수는 블록레벨스코프를 가지므로 코드 블록 내에서 선언된 변수는 지역 변수이다. 따라서 지역 변수도 해당 스코프에서 호이스팅되고 코드 블록의 선두부터 초기화가 이루어지는 지점까지 일시적 사각지대에 빠진다. 

 

* 호이스팅 우선순위

- 변수 선언문 > 함수 선언문

'Javascript&Typescript' 카테고리의 다른 글

Splice()  (0) 2021.06.17
Shallow Copy & deep Copy  (0) 2021.03.23
Iterable & Iterator  (0) 2021.02.23
FP & OOP  (0) 2021.02.22
classical & prototypal inheritance in javascript  (0) 2021.02.22