본문 바로가기
[JavaScript]

[javascript] 호이스팅(hoisting)과 일시적 사각 지대(TDZ) + var, let, const

by 쥰5017 2022. 10. 5.

 

 

var, let, const

자바스크립트에서 변수를 선언하는 키워드는 세 가지이다. var는 최근 사용을 지양하는 키워드이지만 javascript info의 문구를 그대로 가져와 표현하자면 '오래된 스크립트에서 당신을 기다리고 있는 괴물 같은 존재'이다.

 

우선, var는 블록 스코프가 없다. 블록 스코프가 없다는 것은 블록 밖에서도 var에 접근할 수 있다는 말이다.

if (true) {
  var test = true;
}

alert(test); // true(if 문이 끝났어도 변수에 여전히 접근할 수 있음)

 

var는 변수의 중복 선언도 가능하다.

var user = "Pete";
var user = "John"; // 이 "var"는 아무것도 하지 않습니다(이전에 이미 선언됨).
// ...에러 또한 발생하지 않습니다.

alert(user); // John

 

이 두 가지 특성 때문에 '괴물'이라고 표현한 것이다. 위의 코드 예시들은 간단하지만,,, 몇백 줄 넘어가는 코드를 작성하다가 변수 하나라도 잘못 건드리는 날이 온다면,,, var를 사용한 나 자신을 원망해야지 var에게는 잘못이 없다. 

 

 

Hoisting?

호이스팅이란 자바스크립트의 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다. 변수와 함수의 선언을 해당 스코프의 최상단으로 끌어올려 먼저 처리한다는 것이다. 특히 var는 그 특성 때문에 독특하게 호이스팅이 된다.

function sayHi() {
  console.log(phrase); // output: undefined

  phrase = "Hello"; // 할당은 실행 흐름이 해당 코드에 도달했을 때 처리
  var phrase; // 선언은 함수 시작 시 처리
  
  console.log(phrase); // output: Hello
}

sayHi();

위 코드에서 phrase에 대한 선언(var phrase)이 console.log(phrase)보다 아래에 있음에도 불구하고 undefined이 출력된다. (선언과 초기화는 되었고, 값이 할당되지 않은 상태) 이걸 let으로 바꾸면 오류난다.

function sayHi() {
  console.log(phrase); // Cannot access 'phrase' before initialization

  phrase = "Hello";
  let phrase; 

}

sayHi();

 

변수가 초기화되기 전에는 접근할 수 없다는 문구가 뜬다. 그럼 let과 const는 호이스팅이 되지 않는 걸까?

 

 

Temporal dead zone

결론부터 말하자면 let, const도 호이스팅이 되긴 한다. 다만, 초기화 전에 접근을 시도하면 오류가 발생하는 TDZ라는 구역이 있다. TDZ에 대해 알기 전에 var, let, const의 호이스팅 방식의 차이를 짚고 넘어가자.

  • var: 선언과 초기화가 호이스팅 된다.
  • let, const: 선언만 호이스팅 된다.

TDZ는 선언과 초기화 사이에 발생하는 구역이다. 이 사각 지대는 코드의 작성 순서가 아니라 코드의 실행 순서(시간)에 의해 형성된다. 이 구역에서 할당되지 않은 변수를 사용하면 에러가 발생한다.

let과 const가 선언되고 초기화되기 전 TDZ

  // TDZ가 스코프 맨 위에서부터 시작
  const func = () => console.log(letVar); // OK

  // TDZ 안에서 letVar에 접근하면 ReferenceError

  let letVar = 3; // letVar의 TDZ 종료
  func(); // TDZ 밖에서 호출함

 

 

 

 

댓글