변수, 함수 선언이
실행되기 전에 메모리에 먼저 올라가는 동작
코드가 작성된 위치와 관계없이 선언 부분이최상단으로 끌어올려진 것처럼동작
자바스크립트 엔진은 코드를 위에서 아래로 단순히 한 줄씩 실행하지 않고, 먼저 실행 컨텍스트를 만들고 내부에 변수를 등록한다.
📌 실행 컨텍스트?
자바스크립트 코드가 실행되는 환경을 추상화한 개념으로, 자바스크립트의 동작 원리를 담고 있는 핵심 개념
자바스크립트 엔진은 실행 컨텍스트를 통해 식별자와 스코프를 관리
선언문이 코드 아래쪽에 있어도, 실행 시점에는 이미 메모리에 올라와 있어 접근이 가능
개발자가 보기에 “끌어올려진 것처럼 보이는 현상”이라서 Hoisting이라는 이름이 붙었다.
int main() {
printf("%d\n", x); // ❌ Error: undeclared identifier
int x = 10;
} 선언 전에 변수를 쓰면 바로 컴파일 에러, 실행까지 가지도 못함print(x) # ❌ NameError: name 'x' is not defined
x = 10 선언이 나오기 전에는 참조하게 된다면 런타임 에러 발생console.log(x); // undefined
var x = 10; 다른 언어라면 에러가 나야 하지만, var 키워드로 선언한 변수는 어떠한 값도 할당하지 않아도 “호이스팅” 덕분에 undefined가 출력자바스크립트 엔진은 변수 선언을 3단계에 거쳐 수행
undefined를 할당해 초기화한다.undefined로 초기화된 변수에 실제 값을 할당한다.var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한 번에 이루어진다.
따라서 변수 선언문 이전에 변수에 접근하여도 Environment Record에 변수가 존재하기 때문에 에러가 발생하지 않고 undefined를 반환한다.
Environment Record?
실행 컨텍스트의 객체 중 변수, 매개변수, 인수, 함수 선언 같은 정보를 담는 객체
let과 const는 선언 단계만 먼저 실행 컨텍스트에 등록되고 초기화 단계는 변수 선언문을 만났을 때 실행된다.
따라서 변수 선언문 이전에 변수에 접근하면 Environment Record 에 변수가 존재하지만 초기화되어 있지 않기 때문에 에러가 발생한다.
이 사이 구간을 TDZ(Temporal Dead Zone)라 부르며, 접근 시 ReferenceError 발생
TDZ(Temporal Dead Zone)?
변수가 스코프에 선언되어 존재하지만, 아직 초기화되지 않아 접근할 수 없는 구간
이 구간에서 해당 변수에 접근하면
ReferenceError(참조 에러) 발생
var: 선언과 초기화(undefined)까지 호이스팅됨 → 선언 전에 접근 가능하지만 undefined 반환let/const: 선언만 호이스팅됨. 초기화되기 전까지 TDZ에 묶여 있어 접근 시 ReferenceError(참조 에러)console.log(a); // undefined
var a = 10;
console.log(b); // ReferenceError (TDZ)
let b = 20;
sayHi(); // "Hi"
function sayHi() {
console.log("Hi");
} 실행 컨텍스트 생성 단계에서, 함수 선언문은 함수 객체 자체가 메모리에 저장되기 때문var, let, const) 변수 호이스팅 규칙을 따름var
- 준비 단계: var name만 등록 + undefined로 초기화
- 실행 단계: 대입문 도달 시 함수 객체가 그때 들어감
- 선언 전 호출 → TypeError: name is not a function (이름은 있지만 값이 아직 undefined)
greet(); // TypeError: greet is not a function
var greet = function() { console.log("Hello"); };
let, const
- 준비 단계: 이름만 등록(TDZ)
- 실행 단계: 선언문에서 초기화 + 대입
- 선언 전 접근/호출 → ReferenceError (TDZ)
greet(); // ❌ ReferenceError
let greet = function () {
console.log("Hello");
};
ECMAScript, ESLint, 코드 컨벤션을 참고하였음
constconst로 고정 → 의도 명확, 실수 줄임.letvar는 금지const 함수 표현식(또는 화살표 함수)