댓글을 작성하려면 로그인이 필요합니다.
아직 작성된 댓글이 없어요. 첫 댓글을 남겨주세요!

자바스크립트의 스코프, 클로저, 호이스팅이 어떻게 동작하는지 이해하려면 결국 실행 컨텍스트를 알아야 한다. 이 개념 하나가 JS의 핵심 동작 원리를 꿰뚫는 열쇠다.
자바스크립트 코드가 실행되기 위해 필요한 환경 정보들을 모아둔 객체다.
코드를 실행하려면 "현재 어떤 변수를 쓸 수 있지?", "this는 뭘 가리키지?", "바깥 스코프엔 뭐가 있지?" 같은 정보들이 필요하다. 실행 컨텍스트는 이 정보들을 한 곳에 담아 관리한다.
실행 컨텍스트는 크게 두 종류가 있다.
실행 컨텍스트들은 콜스택(Call Stack) 에 쌓인다.
function b() {
console.log('b');
}
function a() {
b();
}
a();
[b 실행 컨텍스트] ← 현재 실행 중
[a 실행 컨텍스트]
[전역 실행 컨텍스트]
자바스크립트는 싱글 스레드라 콜스택의 맨 위에 있는 컨텍스트 하나만 실행한다. b()가 끝나면 pop되고 a()로 돌아오는 구조다.
이벤트 루프에서 큐의 콜백함수가 콜스택으로 넘어올 때도 마찬가지다. 콜백함수가 실행되는 순간 새 실행 컨텍스트가 생성되어 콜스택에 push된다. 즉, 콜백함수 자체가 실행 컨텍스트는 아니고, 실행 컨텍스트는 함수가 실행될 때 만들어지는 것이다.
실행 컨텍스트는 내부적으로 세 가지 정보를 갖는다.
현재 스코프의 변수와 함수 선언을 저장하고, 외부 스코프에 대한 참조도 가진다. 클로저가 동작할 수 있는 이유가 바로 이 외부 참조 덕분이다.
function outer() {
const x = 10;
return function inner() {
console.log(x); // inner의 Lexical Environment → outer 스코프 참조
};
}
var로 선언된 변수를 관리한다. 초기에는 Lexical Environment와 같지만, var의 함수 스코프 특성을 처리하기 위해 별도로 존재한다.
현재 컨텍스트에서 this가 무엇을 가리키는지 저장한다. 전역에서는 window(브라우저), 메서드 호출에서는 해당 객체, 화살표 함수는 자신만의 this 바인딩을 갖지 않고 상위 컨텍스트의 것을 그대로 사용한다.
실행 컨텍스트가 만들어질 때는 항상 두 단계를 거친다.
코드를 한 줄씩 실행하기 전에, 전체를 훑어보고 어떤 변수와 함수가 있는지 파악해서 미리 메모리에 등록한다. 이 과정에서 일어나는 것이 바로 호이스팅이다.
1단계에서 파악한 정보를 바탕으로 코드를 위에서 한 줄씩 실행하며 값을 할당하고 함수를 호출한다.
단순히 "메모리에 미리 올려두기 위해서"가 아니다. 핵심 목적은 실행 전에 스코프와 변수 바인딩을 확정짓기 위해서다.
자바스크립트는 렉시컬 스코프를 따른다. 즉, 변수가 어느 스코프에 속하는지는 코드를 작성한 위치에 의해 결정된다. 이 스코프 관계를 확정하려면 실행 전에 코드 구조를 먼저 전체적으로 훑어야 한다.
덕분에 얻는 부가적인 효과가 함수를 선언 전에 호출할 수 있다는 것이다.
greet(); // 선언 전에 호출해도 동작
function greet() {
console.log('hello');
}
호이스팅은 1단계에서 변수와 함수 정보를 끌어올려 등록하는 동작인데, 선언 방식에 따라 결과가 다르다.
| 선언 방식 | 호이스팅 | 초기화 |
|---|---|---|
var | ✅ | undefined로 초기화 |
function 선언문 | ✅ | 함수 전체가 올라감 |
let / const | ✅ | 초기화 안 됨 (TDZ) |
let과 const도 호이스팅은 된다. 단, 초기화가 되지 않은 채로 등록되어 선언문 이전에 접근하면 ReferenceError가 발생한다. 이 구간을 TDZ(Temporal Dead Zone, 일시적 사각지대) 라고 한다.
console.log(a); // undefined (var는 초기화됨)
console.log(b); // ReferenceError (TDZ)
var a = 1;
let b = 2;
let/const가 더 안전한 이유가 바로 TDZ 덕분이다. 선언 전에 실수로 변수를 사용하면 에러로 즉시 알려주기 때문이다.
실행 컨텍스트는 자바스크립트 코드가 실행될 때 필요한 환경 정보를 담은 객체입니다. 스크립트가 처음 시작될 때 전역 실행 컨텍스트가 생성되고, 이후 함수가 호출될 때마다 새로운 실행 컨텍스트가 만들어져 콜스택에 쌓입니다. 자바스크립트가 싱글 스레드이기 때문에 항상 콜스택 최상단의 컨텍스트 하나만 실행되며, 이벤트 루프를 통해 들어온 콜백함수도 예외 없이 실행 시점에 컨텍스트가 생성됩니다.
각 실행 컨텍스트는 내부에 세 가지 정보를 갖습니다. Lexical Environment는 현재 스코프의 변수와 외부 스코프 참조를 담고 있어 클로저의 근거가 됩니다. Variable Environment는 var 변수를 관리하고, This 바인딩은 현재 컨텍스트에서 this가 무엇인지를 기록합니다.
컨텍스트 생성은 2단계로 이루어집니다. 평가 단계에서는 코드를 실행하기 전에 전체를 훑어 스코프와 변수 바인딩을 확정짓고, 실행 단계에서 비로소 코드를 한 줄씩 처리합니다. 이 과정에서 호이스팅이 발생하는데, var는 undefined로 초기화되어 끌어올려지고, 함수 선언문은 전체가 올라가지만, let과 const는 호이스팅은 되되 초기화가 되지 않아 선언 전 접근 시 TDZ로 인한 ReferenceError가 발생합니다.