TDZ와 호이스팅

LOCA·2022년 6월 17일
1

자바스크립트

목록 보기
1/10
post-thumbnail

TDZ(Temporal Dead Zone) - 일시적인 녹색사각지대

Javascript 변수 키워드에는 var, let, const가 있다.

var는 한번 선언된 변수를 다시 선언할 수 있다.

var name = 'Jihun';
console.log(name); // Jihun

var name = 'kimjihun';
console.log(name); // Kimjihun

var는 선언하기 전에 사용할 수 있다.

console.log(name); // undefined
var name = 'Jihun';

바로 호이스팅(hoisting)이 일어나기 때문이다.

# 결과가 undefined가 발생되는 이유는 선언은 호이스팅되지만 할당은 호이스팅 되지 않기 때문이다.
var name;
console.log(name); // undefined
name = 'Jihun';

많은 Javascript 서적과 강좌에는 const, let은 호이스팅이 되지 않는다고 명시되어 있는 경우가 종종있다. 과연 그럴까? 여기서 정확하게 호이스팅의 뜻을 알아보자.

호이스팅이란 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것처럼 행동하는 것을 의미한다.

그런데 var 키워드처럼 동작하지 않고 에러가 발생되는 걸까? 바로. Temporal Dead Zone(TDZ)라는 것 때문에 일어난다.

# hoisting
console.log(name); // TDZ😱
const name = 'Jihun’; // 함수 선언 및 할당
console.log(name); //사용 가능

위에 TDZ 영역에 있는 변수들은 사용 가능하지 않는데, 바로 let과 const는 TDZ에 영향을 받기 때문이다. 이말은 곧 할당을 하기 전에는 사용할 수 없다는 말과 같으나 이는 코드를 예측가능하게 하고 잠재적은 버그를 줄일 수 있다는 장점을 갖는다.

# 이 코드는 문제가 없다.
let age = 10;
function showYourAge() {
	console.log(age);
}
showYourAge(); // 10

# 이 코드는 문제가 있다.
let age = 10;
function showYourAge() {
  console.log(age);
  let age = 20;
}
showYourAge(); // ReferenceError: Cannot access 'age' before initialization

앞서 말한 것처럼 let과 const는 호이스팅이 되지 않기 때문에 위에 작성한 2번째 코드에 발생되는 문제의 원인이라고 생각할 것이다.

호이스팅은 스코프 단위로 발생되는데, 위의 예시에서의 스코프는 함수 내부를 의미하며, 함수 안에서 let 키워드로 선언한 변수가 호이스팅을 일으킨다. 만약 let 키워드로 선언한 변수가 우리가 알고 있는 것처럼 호이스팅이 일어나지 않는다면 저 바깥에 선언한 let 키워드의 변수의 값 10이 출력되었어야 했다.

var 키워드는 선언과 동시에 초기화 단계가 이루어지지만, let 키워드는 선언 단계와 초기화 단계가 분리되어 있어, 호이스팅이 일어날 경우 선언 단계는 위로 끌어올려지지만 초기화 단계는 실제 코드에 도달할 대 실행되기 때문에 레퍼런스 에러가 발생되는 것이다.

변수의 생성과정은 1. 선언 단계, 2.초기화 단계, 3.할당 단계. 총 3가지 단계로 구분지을 수 있다.

var 키워드

  1. 선언 및 초기화 단계
  2. 할당 단계

let 키워드

  1. 선언 단계
  2. 초기화 단계
  3. 할당 단계

const 키워드

  1. (선언 + 초기화 + 할당) 단계

위에 설명대로 const 키워드로 변수 생성 시 선언, 초기화 및 할당을 동시에 선언하지 않으면 아래와 같은 에러가 발생된다.

let name;
name = 'Jihun';

var age;
age = 30;

# Uncaught SyntaxError: Missing initializer in const declaration
const gender; // 선언만하고 할당은 하지 않았기 때문에 에러발생
gender = 'male';

그리고, var, let, const 키워드는 스코프도 서로 다르다.

var 키워드: 함수 레벨 스코프(function-level-scoped)

# 함수 레벨 스코프(function-level-scoped) <<- 함수블록내에서 선언된 변수는 해당 함수 블록내에서만 사용가능
function addNum(num1, num2) {
  var result = num1 + num2;
}
add(2, 3); // 5

# 함수블록 바깥에서 함수내부에서 var키워드로 선언된 result 호출시 에러 발생
console.log(result) // Uncaught ReferenceError: result is not defined.

# 하지만 var는 block-level-scoped가 아니기 때문에 블록 외부에서 사용가능하다.
const age = 10;
if(age >= 20) {
	var adult = '성인';
}
console.log(adult); // 성인

let, const 키워드: 블록 레벨 스코프(block-level-scoped) - if 문, while문, tyr/catch문 등

# block-level-scoped - 코드블록내에서 선언된 변수는 해당 블록내에서만 사용가능하며, 외부에서는 접근할 수 없다., 한마디로 지역변수(local variable)이다.
function name() {
	// block-level-scoped
}

if() {
   // block-level-scoped
}

for(let i = 0; i <= 10; i++) {
  // block-level-scoped
}

정리

TDZ(Temporal Dead Zone)란, 변수가 스코프의 시작 지점부터 초기화가 시작되는 지점까지의 구간을 말한다.let과 const키워드는 var키워드처럼 호이스팅(hoisting)이 일어난다.

profile
helloWorld

0개의 댓글