본문 바로가기
JavaScript

JavaScript, 호이스팅과 TDZ

by nacjji 2022. 11. 18.
호이스팅이란?

- 변수와 함수의 메모리공간을 선언 전에 미리 할당하고, 변수의 선언과 초기화를 분리한 후 선언부를 코드의 최상단으로 옮기는 것이다. 

- 호이스팅을 이해하기 전에 scope 의 개념을 이해하면 좋다. 

https://nacjji.tistory.com/46

 

Scope

1. Scope : 참조 대상 식별자(identifier, 변수, 함수의 이름과 같이 어떤 대상을 다른 대상과 구분하여 식별할 수 있는 유일한 이름)를 찾아내기 위한 규칙 var x = 'global' function scope_prac () { var x = 'functio

nacjji.tistory.com

- 자바스크립트는 변수를 선언할 때 선언부에 var, let, const 키워드를 사용한다. 

- var 로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화 하는 반면, let 과 const 로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않는다. 

 

호이스팅 예제
function myDog(name){
    console.log(`my dog is ${name}`)
}
myDog("마음")
→ my dog is 마음

- 일반적으로 코드를 작성할 때 위에서 아래로 작성하고 실행한다.  

- 하지만 아래와 같은 코드도 정상적으로 실행된다. 

myDog("마음")
function myDog(name){
    console.log(`my dog is ${name}`)
}
→ my dog is 마음

- 이는 함수의 선언부인 function 이하의 코드들은 코드의 최상단으로 호이스팅 되어 함수를 선언하고 실행한 것과 같은 기능을 수행하는 것이다. 

화살표 함수와 호이스팅

- ES6 에서 추가된 기능인 화살표 함수는 호이스팅이 되지 않는다. 

myDog("마음")
const myDog = (name)=>{
    console.log(`my dog is ${name}`)
}
ReferenceError: Cannot access 'myDog' before initialization

- 화살표 함수로 선언된 함수 myDog 이 선언되기 전에 함수를 실행하면 myDog 함수가 초기화되기 전에 사용할 수 없다는 에러문구가 출력된다. 

- 그 이유는 변수 myDog은 호이스팅이 되지만 화살표 함수를 할당, 즉 초기화 하는 것은 호이스팅이 되지 않는다. 컴퓨터는 변수 myDog을 함수가 아닌 일반 변수로 취급하기 때문이다. 

- 위 코드는 아래와 같다. 

myDog("마음")
const myDog
SyntaxError: Missing initializer in const declaration

 

TDZ(Temporal Dead Zone)

- TDZ 는 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 의미한다. 

- 변수 선언은 3단계를 거쳐서 이루어진다. 

  • 선언 단계 : 변수를 실행 컨텍스트의[각주:1] 변수 객체에 등록하는 단계
  • 초기화 단계 : 실행 컨텍스트에 존재하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계, 이 때 할당된 메모리는 undefined로 초기화된다. 
  • 할당단계 : 사용자가 undefined로 초기화된 메모리에 다른 값을 할당하는 단계

- var 키워드로 선언한 변수와 let,const 키워드로 선언한 변수는 차이점이 있다. 

  • var 변수는 선언 전에 선언단계와 초기화 단계를 동시에 진행한다. 
  • 자바스크립트는 실행 컨텍스트 변수 객체에 변수를 등록하고 메모리에 undefined 를 할당한다. 
  • 따라서 변수에 값을 할당하기 전에 호출을 하면 undefined가 출력된다.
console.log(variable)

var variable = 'tdz'
→ undefined

 

  • let 과 const 로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 
  • 실행 컨텍스트에 변수를 등록했지만 메모리에 할당되지 않기 때문에 값 할당 전에 변수를 호출하면 참조에러(ReferenceError)가 발생한다(호이스팅이 되지 않는다). 
console.log(variable)

let variable = 'tdz'
ReferenceError: Cannot access 'variable' before initialization

 

- 다시 TDZ로 돌아와서, TDZ는 스코프의 시작부터 변수의 초기화 단계까지의 구간을 의미한다. 

- let, const 로 선언한 변수는 실행 컨텍스트 변수 객체에 등록이 되어 호이스팅이 이루어지지만, TDZ 구간에 의해 메모리가 할당이 되지 않아 참조 에러가 발생된다. 

- 함수는 변수 선언 3단계를 동시에 진행해 어떤 위치에서 함수를 실행해도 함수는 실행된다. 

 

 

 

 

 

  1.  실행할 코드에 제공할 환경 정보들을 모아놓은 객체 [본문으로]