본문 바로가기

자바스크립트

Hoisting과 Temporal Dead Zone

호이스팅(Hoisting)

자바스크립트에서의 호이스팅은 단순히 ‘끌어올린다’라는 생각만 하는데 실제로 아래 코드를 실행하면 다음과 같은 결과가 일어난다.

console.log(x); //undefined
var x = 10;

이 코드에서 console.log(x);는 아직 변수 x가 선언되지 않았기 때문에 오류가 발생할 것 같지만 undefined가 출력된다. 프로그램 중간에서 변수를 선언하더라도 프로그램 처음에 선언된 것처럼 다른 문장 앞에 생성되기 때문이다. 이를 변수 선언의 끌어올림(Hoisting)이라고 한다.

호이스팅이 정말 코드를 위로 끌어올리는 것은 아니고, 변수나 함수를 선언 이전에 사용할 수 있게 끌어 올려지는 것처럼 보이게 하는 것이다.

 

호이스팅은 모든 선언들을 끌어 올려서 해당 유효 범위(스코프)의 최상단에 선언하는 것을 의미한다. (이때 변수의 스코프에 따라 전역 스코프일 경우 스크립트 단위의 최상단으로 끌어올려지고, 함수 범위일 경우 함수 내 최상단으로 끌어 올려진다.)

여기서 중요한점은 선언된 것을 끌어올린다는 것과, 선언과 할당된 값을 전부 끌어올리는 것이 아니라 선언만 끌어올려진다라는 점이다. 변수 선언부 var x는 끌어올리지만 대입부 x = 10은 끌어올리지 않는다.

 

자바스크립트에서 함수를 선언할 때 함수선언식함수표현식 2가지 방법으로 함수를 생성할 수 있다.

declaration(); //"선언식"
expression(); //ReferenceError

//함수 선언식
function declaration() {
	console.log("선언식");
}

//함수 표현식
const expression = function() {
	console.log("표현식");
}

이때 선언으로 생성된 함수만이 호이스팅이 가능하다.

 

 

var와 달리 let, const 변수 선언에서는 호이스팅이 발생하지 않는 것처럼 보인다. 는 TDZ 때문이다. 

console.log(y); //ReferenceError
console.log(z); //ReferenceError

let y = 20;
const z = 30;

 

TDZ(Temporal Dead Zone)란?

한국말로 번역하면 일시적인 사각지대라는 의미다. TDZ는 변수를 사용하는 것을 비허용하는 개념상의 공간이다. TDZ에 있는 값에 접근하게 되면 ReferenceError: Cannot access 'xxx' before initialization 에러가 발생한다.

(선언 단계 ~ 초기화 시작 전까지 구간)

 

변수 생성단계

자바스크립트에서 변수는 다음 3단계를 거쳐 생성된다.

  1. 선언 단계
    • 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계
    • 이 변수 객체는 스코프가 참조하는 대상이 된다.
  2. 초기화 단계
    • 실행 컨텍스트에 존재하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계
    • 이 단계에서 할당된 메모리에는 undefined로 초기화된다.
  3. 할당 단계
    • 사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계

*실행 컨텍스트 : 코드가 실행되기 위해 필요한 환경

 

var의 경우

  1. var 키워드는 변수 선언 시 선언초기화를 동시에 진행
  2. 자바스크립트는 실행 컨텍스트 변수 객체의 변수를 등록하고 메모리를 undefined로 만듦
  3. 변수에 값을 할당
  4. 변수는 값을 가지게 된다.

→ 선언과 동시에 초기화를 진행하여 메모리를 할당해주기 때문에 호이스팅이 될 때 참조가 가능해서 오류가 발생하지 않음

 

let과 const의 경우

let과 const의 경우 var와 달리 선언초기화를 따로 진행한다. 그렇기 때문에 선언단계에서 실행 컨텍스트에 변수를 등록했지만, 메모리가 할당되지 않아 접근할 수 없어서 ReferenceError가 발생한다.(선언은 되어 있지만 변수에 값을 담기위한 메모리에 공간이 확보되지 않은 상태)

호이스팅은 되지만 접근할 수가 없어서 호이스팅이 되지 않는 것처럼 보이는 것

 

함수 선언식의 경우

함수 선언식의 경우 선언, 초기화, 할당이 동시에 진행되기 때문에 호이스팅도 되고 실행도 가능하다.

 

 

  • 호이스팅도 되고 참조 오류도 생기지 않는 경우
    var, 함수 선언식, import
  • 호이스팅은 되지만 참조 오류가 생기는 경우
    let, const, class구문, class constructor() 내부의 super() 메소드 (상속받은경우), 기본 매개변수(ES6)

 

 

[JS] 호이스팅과 TDZ에 대하여

[JS] 호이스팅과 TDZ (Temporal Dead Zone) - let도 호이스팅이 된다!

 

'자바스크립트' 카테고리의 다른 글

this  (0) 2023.03.17
callback, promise, async/await  (0) 2023.03.14
이벤트 위임  (0) 2023.03.11
자바스크립트의 배열  (0) 2023.03.08
스코프  (0) 2023.03.03