티스토리 뷰

 JavaScript의 변수 선언에서 호이스팅과 일시적 사각지대(TDZ, Temporal Dead Zone)는 중요한 개념입니다. 이 두 개념은 변수의 선언과 초기화, 그리고 변수가 접근 가능한 시점에 영향을 미칩니다.

 

호이스팅 (Hoisting)

호이스팅은 변수나 함수의 선언이 끌어올려지는 것처럼 보이는 현상을 말한다.(실제론 끌어올려지지 않음) 


Javascript는 런타임 이전에, 코드 평가 과정을 거치면서 코드를 실행하기 위한 준비를 한다.

이때 자바스크립트 엔진은 모든 선언문을 찾아서 먼저 실행한다. 이 때문에 선언문이 끌어올려져서 실행되는 것처럼 보이는 것이다.

 

초기화는 호이스팅되지 않습니다.

 

'var'의 호이스팅

'var'로 선언된 변수는 선언만 호이스팅되며, 초기화는 원래 코드 위치에 남습니다.

console.log(a); // undefined
var a = 1;
console.log(a);	// 1

 

위 예제에서 'var a' 선언은 호이스팅되므로, 첫 번째 콘솔은 'undefined'를 출력합니다. 

 

일시적 사각지대 (TDZ, Temporal Dead Zone)

일시적 사각지대(TDZ)는 'let'과 'const'로 선언된 변수가 초기화되기 전까지 접근이 불가능한 기간을 말합니다. 변수가 선언된 블록의 시작부터 실제 선언 위치까지 TDZ에 해당합니다. 이 구역에서 변수에 접근하려 하면 'ReferenceError'가 발생합니다.

console.log(b);	// ReferenceError: Cannot access 'b' before initialization
let b = 10;
console.log(b);	// 10

console.log(c);	// ReferenceError: Cannot access 'c' before initialization
const c = 15;
console.log(c); // 15

 

위 예제에서 'let'과 'const'로 선언된 변수 'b'와 'c'는 선언 전에 접근할 수 없으며, TDZ로 인해 'ReferenceError'가 발생합니다.

 

'var' vs 'let' vs 'const'

'var'

  • 스코프 : 함수 스코프(function scope)를 가집니다. 이는 변수가 선언된 함수 내에서만 유효하며, 블록 스코프(if, for, while 등)를 따르지 않습니다.
  • 재선언 가능 : 같은 스코프 내에서 동일한 이름의 변수를 여러 번 선언할 수 있습니다.
  • 호이스팅 : 선언이 호이스팅되어 'undefined'로 초기화됩니다.
  • TDZ 없음 : 'var'로 선언된 변수는 초기화 전에 접근할 수 있습니다.

'let'

  • 스코프 : 블록 스코프(block scope)를 가집니다. 이는 변수가 선언된 블록 내에서만 유효합니다.
  • 재선언 불가 : 같은 스코프 내에서 동일한 이름의 변수를 다시 선언할 수 없습니다.
  • 호이스팅 : 선언이 호이스팅되지만 초기화는 실제 선언 위치에서 이루어집니다.
  • TDZ 존재 : TDZ로 인해 초기화 전에 변수에 접근하면 'ReterenceError'가 발생합니다.

'const'

  • 스코프 : 블록 스코프(block scope)를 가집니다.
  • 재선언 및 재할당 불가 : 같은 스코프 내에서 동일한 이름의 변수를 다시 선언할 수 없으며, 재할당 할 
  • 호이스팅 : 선언이 호이스팅되지만 초기화는 실제 선언 위치에서 이루어집니다.
  • TDZ 존재 : TDZ로 인해 초기화 전에 변수에 접근하면 'ReferenceError'가 발생합니다.
  • 초기화 필요 : 'const'로 선언된 변수는 선언과 동시에 초기화되어야 합니다.

 

함수 선언과 변수 호이스팅의 차이

 

함수 선언식은 변수 선언과 달리 함수 전체가 호이스팅됩니다. 즉, 함수 선언이 코드의 맨위로 올라가며 전체 함수 본문이 호이스팅됩니다.

exFunction();`// exFunction

function exFunction() {
    console.log("exFunction");
}

 

 

반면, 함수 표현식은 변수로 처리되어 변수 선언만 호이스팅되며 초기화는 나중에 이루어집니다.

exFunction();	// ReferenceError: Cannot access 'exFunction' before initialization

const exFunction = () => {
    console.log("exFunction");
};

 

 

정리

  • 호이스팅 : 모든 변수 선언('var', 'let', 'const')은 호이스팅되지만, 'var'는 초기화되지 않은 상태에서 'undefined'로 접근 가능하고, 'let'과 'const'는 TDZ로 인해 초기화 전에 접근할 수 없습니다.
  • TDZ : 'let'과 'const'는 선언 블록의 시작부터 변수 선언 위치까지 TDZ를 가지며, 이 구역 내에서는 변수에 접근할 수 없습니다.