ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION820 / 1500
언어·런타임난이도 하5분 답변 목표 · 보강본

함수 안에서 선언문보다 먼저 변수를 읽었더니 var는 undefined이고 let·const는 ReferenceError입니다. 변수의 생성과 초기화 시점은 어떻게 다른가요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

var와 let, const는 선언이 코드 아래에 있다는 사실만으로 같은 결과를 내지 않습니다.

바인딩 준비와 초기화

function sample() {
  console.log(a); // undefined
  var a = 1;
  try { console.log(b); } catch (e) { console.log(e.name); } // ReferenceError
  let b = 2;
  try { console.log(c); } catch (e) { console.log(e.name); } // ReferenceError
  const c = 3;
}
sample();

함수 실행 환경을 만들 때 var a의 바인딩은 먼저 만들어지고 초기값 undefined를 받습니다. a = 1이라는 할당은 실제 실행 위치에서 일어나므로 그 전에는 undefined입니다. 이를 흔히 호이스팅이라고 부르지만, 값 전체가 위로 이동하거나 코드가 재배열되는 것은 아닙니다. 함수 선언문처럼 선언과 함수 객체 준비가 함께 이뤄지는 문법은 별도의 규칙을 가집니다.

let과 const도 블록 시작 시 식별자를 위한 렉시컬 바인딩이 준비되지만, 선언문을 실행해 초기화하기 전까지는 값을 읽을 수 없는 일시적 사각지대(TDZ)에 있습니다. 그래서 아래 선언이 존재한다는 이유로 typeof b조차 안전하지 않습니다. 이 구간에서 읽거나 할당하면 ReferenceError이고, const는 초기화 뒤 재할당도 허용하지 않습니다. 블록 밖의 같은 이름 변수를 가리는 경우에도 안쪽 TDZ가 우선합니다.

선언 종류별 사용 시점

실무에서는 선언을 사용 위치보다 앞에 두고, 기본적으로 블록 스코프인 let과 const를 선택하는 편이 읽기와 오류 발견에 유리합니다. var의 동작을 근거로 선언문을 자유롭게 앞당겨도 된다고 판단하지 말고, 특히 조건문·반복문에서 실제 스코프와 초기화 시점을 확인하겠습니다.

선택 기준과 검증

TDZ는 값이 undefined인 구간이 아니라 접근 자체가 금지된 구간입니다. 함수 선언문, 함수 표현식, module import는 준비와 초기화 규칙이 서로 다르므로 모두 호이스팅 한 단어로 설명하지 않겠습니다. 선언 전 typeof를 안전성 검사로 쓰지 말고, 모듈과 일반 스크립트에서 동일한 이름이 어떤 환경 레코드를 가리키는지 확인하겠습니다.

TDZ는 코드의 위아래 위치만으로 정해지는 것이 아니라 실제 초기화 전까지의 시간 구간입니다. let 변수를 읽는 클로저를 먼저 만들어도 그 함수를 초기화 뒤에 호출하면 문제가 없을 수 있습니다. 반대로 함수 호출을 초기화 전에 수행하면 같은 소스라도 ReferenceError가 됩니다. 함수 생성과 함수 본문의 실행 시점을 구분해야 선언 이동의 안전성을 판단할 수 있습니다.

바깥에 x가 있어도 안쪽 블록에서 let x를 선언하면 블록 시작부터 안쪽 바인딩이 이름을 가립니다. 초기화 전 접근이 바깥 x로 되돌아가는 것이 아닙니다. 모듈에서는 import가 살아 있는 바인딩을 연결하므로 순환 의존 중 초기화되지 않은 값을 너무 일찍 읽는 문제가 생길 수 있습니다. 선언을 사용보다 앞에 둔다는 지역 규칙뿐 아니라 모듈 초기화 과정에서 어떤 값을 즉시 사용하는지도 확인하겠습니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • var의 초기화와 대입 실행을 분리한다.
  • let·const의 TDZ와 블록 스코프를 설명한다.
  • 함수 선언·표현식과 실제 사용 위치를 검증한다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • 호이스팅을 대입 값까지 위로 복사하는 재배열로 설명한다.
  • TDZ에서 typeof가 항상 undefined를 반환한다고 말한다.
  • let·const 바인딩은 선언 전혀 준비되지 않는다고 가정한다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

원리부터 공부하고 싶다면

답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.

← 전체 질문 보기