[JS] 호이스팅과 TDZ

2026. 1. 12. 23:19JavaScript

반응형

왜 var는 쓰면 안 되고, React · TypeScript에서는 어떻게 보일까?

자바스크립트를 어느 정도 하다 보면 반드시 듣게 되는 말이 있음

“자바스크립트는 호이스팅 된다”

“TDZ 때문에 에러 나는 거다”

“var는 쓰면 안 된다”

그런데 막상 왜 그런지를 명확히 설명하기는 어려움

이 글에서는 최대한 쉽게, 하지만 동작 원리까지 이해할 수 있게 정리해보고자 함

호이스팅이란 무엇인가?

호이스팅(Hoisting) 이란,

자바스크립트 엔진이 코드를 실행하기 전에

변수와 함수 선언을 먼저 메모리에 등록하는 동작

중요한 점은

“코드가 위로 올라간다”가 아니라

“실행 전에 미리 준비한다” 는 것임

자바스크립트 실행 과정

JS는 코드를 다음과 같이 실행함

호이스팅은 실행 준비 단계에서 발생함

Creation Phase (실행 준비 단계)

  • 스코프 생성
  • 변수 이름 수집
  • 메모리 공간 확보

Execution Phase (실행 단계)

  • 위에서 아래로 한 줄씩 실행

var의 호이스팅

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

왜 에러가 안 날까?

내부적으로는 이렇게 됨

Creation Phase:

a =undefined

Execution Phase:

console.log(a);// undefined
a =10;

  • 이미 a가 undefined로 존재하기 때문

이게 바로 var의 위험한 점임

let / const 와 TDZ

같은 코드, 다른 결과

console.log(b);// ReferenceError
let b =10;

이번엔 에러가 나게됨

왜?


TDZ (Temporal Dead Zone)

TDZ란?

let / const 변수가

선언은 되었지만 아직 사용할 수 없는 구간

TDZ 구간 시각화

{
// TDZ 시작
console.log(x);// ReferenceError
let x =10;
// TDZ 종료
}
  • 변수 이름은 이미 존재
  • 하지만 선언문을 만나기 전까지 접근 금지

왜 TDZ를 만들었을까?

var의 치명적인 문제

if (true) {
console.log(count);// undefined
var count =10;
}
  • 명백한 버그
  • 하지만 에러 없음
  • 디버깅이 매우 어려움

let / const + TDZ

if (true) {
console.log(count);// ❌ 즉시 에러
let count =10;
}

👉 문제 발생 지점을 즉시 알려줌

TDZ는 불편한 게 아니라

개발자를 보호하기 위한 안전장치다.

왜 var는 쓰면 안 되는가?

함수 스코프 (블록 무시)

if (true) {
var a =1;
}
console.log(a);// 1
if (true) {
let b =1;
}
console.log(b);// ReferenceError
  • var는 블록을 무시함

중복 선언 허용

var x =1;
var x =2;// 에러 없음
let y =1;
let y =2;// 에러

undefined 착시

console.log(a +1);// NaN
var a =10;
  • 에러도 안 나고 결과도 이상함

for 루프 + 클로저 버그

for (var i =0; i <3; i++) {
setTimeout(() =>console.log(i),100);
}
// 3, 3, 3
for (let i =0; i <3; i++) {
setTimeout(() =>console.log(i),100);
}
// 0, 1, 2
  • var는 루프마다 스코프를 만들지 않음

결론

var는 레거시 코드 유지보수용

새 코드에서 쓰는 순간 리뷰 컷

React에서 호이스팅은 어떻게 보일까?

함수 선언식 컴포넌트 (호이스팅 O)

exportdefaultfunctionApp() {
return<Header />;
}

functionHeader() {
return<h1>Hello</h1>;
}

화살표 함수 컴포넌트 (호이스팅 X)

exportdefaultfunctionApp() {
return<Header />;// ReferenceError
}

constHeader = () =><h1>Hello</h1>;
  • Header는 let/const → TDZ

React에서 var가 특히 위험한 이유

  • React에서는 let / const 필수
functionComponent() {
console.log(state);
var state =useState(0);
}
  • undefined 접근
  • Hooks 규칙 위반
  • 런타임 버그

TypeScript에서는 어떻게 되나?

중요한 사실

TypeScript는 런타임에 개입하지 않는다

  • 호이스팅 동작은 JS와 완전히 동일

TS가 막아주는 것들

var x =1;
var x =2;// 컴파일 에러
console.log(a);
let a =1;// 컴파일 에러

 

반응형

'JavaScript' 카테고리의 다른 글

JavaScript this  (0) 2026.03.16
JavaScript Prototype과 __proto__ 이해하기  (0) 2026.03.12