자바스크립트 스코프와 실행 컨텍스트: 내부 동작 원리 파헤치기(Scope, Execution Context)
코드는 잘 작성했는데 예상대로 작동하지 않나요? 그 이유는 "스코프와 실행 컨텍스트"를 모르기 때문일 수 있습니다.
안녕하세요, 개발자 여러분! ICT리더 리치입니다. 자바스크립트를 다루다 보면 변수의 접근 범위, 호출 시점의 오류, undefined 문제 등 예기치 않은 상황들을 자주 마주하게 되죠. 대부분의 문제는 "스코프(Scope)"와 "실행 컨텍스트(Execution Context)" 개념을 정확히 이해하면 해결됩니다.
오늘 포스팅에서는 자바스크립트의 내부 동작 구조를 쉽게 풀어보고, 실무에서 반드시 알아야 할 개념들을 정리해드립니다.
📌 바로가기 목차
| 자바스크립트 디버깅 및 실행 컨텍스트를 주제로 한 대표 이미지 |
1. 스코프(Scope)란 무엇인가요?
자바스크립트에서 스코프(Scope)란 변수에 접근할 수 있는 범위를 의미합니다. 코드를 실행할 때 어떤 변수를 어디서 참조할 수 있는지를 결정하는 중요한 기준이죠. 스코프는 크게 전역 스코프(Global Scope)와 지역 스코프(Local Scope)로 나뉘며, 함수나 블록 단위로 생성됩니다.
2. 렉시컬 스코프와 동적 스코프 차이
자바스크립트는 렉시컬 스코프(Lexical Scope)를 채택하고 있습니다. 이는 코드가 작성된 위치(정적 구조)에 따라 스코프가 결정된다는 의미입니다. 반면, 동적 스코프(Dynamic Scope)는 함수를 호출한 위치에 따라 결정되며, 이는 일부 다른 언어에서 사용됩니다.
| 구분 | 렉시컬 스코프 | 동적 스코프 |
|---|---|---|
| 기준 | 코드 작성 위치 | 함수 호출 위치 |
| 대표 언어 | JavaScript, Python | Bash, Perl |
| 예측 가능성 | 높음 | 낮음 |
3. 실행 컨텍스트의 구조
실행 컨텍스트(Execution Context)는 코드 실행에 필요한 정보를 담고 있는 환경입니다. 자바스크립트는 코드를 실행할 때, 실행 컨텍스트를 생성하여 함수 실행, 변수 참조, this 바인딩 등을 처리합니다.
- Variable Environment: 선언된 변수 정보 저장
- Lexical Environment: 스코프 체인 구조 관리
- This Binding: 현재 컨텍스트의 this 지정
![]() |
| 자바스크립트 스코프와 실행 컨텍스트 개념을 시각적으로 정리한 고퀄리티 인포그래픽 (여성 중심) |
4. 실행 컨텍스트와 호출 스택(Call Stack)
자바스크립트 엔진은 실행 컨텍스트를 호출 스택(Call Stack)이라는 구조로 관리합니다. 가장 먼저 실행된 컨텍스트는 아래에, 나중에 실행된 컨텍스트는 위에 쌓이며, 실행이 끝나면 스택에서 제거됩니다. 이 구조 덕분에 자바스크립트는 동기적 실행을 예측 가능하게 유지할 수 있습니다.
| 호출 흐름 | 호출 스택 |
|---|---|
| main() | [main] |
| main() → foo() | [foo, main] |
| foo() → bar() | [bar, foo, main] |
자바스크립트는 싱글 스레드 언어로, 호출 스택(Call Stack)을 통해 함수 실행 순서를 관리합니다. 함수가 호출되면 실행 컨텍스트가 스택에 쌓이고, 실행이 종료되면 제거(Pop)됩니다. 이 구조를 알면 디버깅, 순서 이해, 성능 최적화에 매우 유용합니다.
아래는 함수 호출 흐름과 호출 스택 구조를 설명하는 자바스크립트 예시입니다.
function funcA() {
console.log('A 시작');
funcB();
console.log('A 끝');
}
function funcB() {
console.log('B 시작');
funcC();
console.log('B 끝');
}
function funcC() {
console.log('C 실행');
}
console.log('메인 시작');
funcA();
console.log('메인 종료');
/* 호출 스택 구조
1. main() → funcA() → funcB() → funcC()
2. funcC()부터 순차적으로 pop
3. 각 단계에서 실행 컨텍스트 생성 및 소멸
실행 결과:
메인 시작
A 시작
B 시작
C 실행
B 끝
A 끝
메인 종료
*/
5. 변수 호이스팅과 TDZ(Temporal Dead Zone)
자바스크립트는 변수 선언을 코드의 최상단으로 끌어올리는 호이스팅(Hoisting)이라는 특성을 가집니다. 그러나 let과 const는 선언 전 접근 시 오류가 발생하는 TDZ(Temporal Dead Zone) 구간이 존재하므로 주의해야 합니다.
호이스팅(Hoisting)이란 변수 및 함수 선언이 스코프 상단으로 끌어올려지는 현상을 의미합니다.
단, let, const는 일시적 사각지대(TDZ)에 있어 초기화 전 접근 시 에러가 발생합니다.
아래 예시는 var, let, const 각각의 호이스팅 동작을 비교한 코드입니다.
console.log(a); // undefined (호이스팅 O)
var a = 10;
// console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;
// console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 30;
function demo() {
console.log(x); // undefined
var x = 5;
console.log(x); // 5
}
demo();
/* 정리:
- var는 선언이 호이스팅되어 undefined 상태로 초기화됨
- let과 const는 TDZ에 존재하며 초기화 전 접근 시 오류 발생
*/
6. 실무에서 주의해야 할 스코프 팁
실무에서 스코프와 실행 컨텍스트를 이해하고 있다면, 예기치 않은 버그를 방지할 수 있습니다. 아래는 현업 개발자들이 자주 실수하는 포인트입니다.
-
함수 내 선언 변수는 항상
let또는const로 선언하세요. - 글로벌 변수 남용은 피하고, 블록 스코프를 적극 활용하세요.
- 클로저(Closure) 사용 시 참조변수에 주의하세요.
자바스크립트는 함수를 실행할 때, 스코프 체인(Scope Chain)을 따라 변수를 검색합니다. 자신의 스코프에 없다면, 외부 렉시컬 환경으로 거슬러 올라가며 탐색하는 구조입니다.
아래는 중첩 함수와 스코프 체인을 설명하는 자바스크립트 예시입니다.
const global = 'G';
function outerFunc() {
const outer = 'O';
function innerFunc() {
const inner = 'I';
console.log(global); // G
console.log(outer); // O
console.log(inner); // I
}
return innerFunc;
}
const myFunc = outerFunc();
myFunc();
/* 변수 탐색 순서:
1. innerFunc → inner
2. outerFunc → outer
3. 전역 컨텍스트 → global
스코프 체인은 함수가 생성된 시점의 렉시컬 환경을 기준으로 생성됩니다.
*/
![]() |
| 호출 스택과 실행 컨텍스트의 내부 구조를 시각화한 자바스크립트 인포그래픽 (남성 중심) |
7. 자주 묻는 질문 (FAQ)
실제로는 함께 동작하기 때문에 하나만 이해하면 전체 흐름을 놓칠 수 있습니다. 두 개념은 함께 공부하는 것이 효율적입니다.
호이스팅은 발생하지만 TDZ로 인해 선언 이전에는 접근할 수 없습니다. 이로 인해 오류가 발생하는 구조입니다.
함수가 호출될 때 생성되고, 함수 실행이 끝나면 호출 스택에서 제거되며 메모리도 해제됩니다.
전역 변수는 전역 실행 컨텍스트의 Variable Environment에 저장되며, global/window 객체에 바인딩됩니다.
변수를 찾을 때 현재 렉시컬 환경에서 찾고, 없으면 외부 렉시컬 환경으로 이동하는 구조로 작동합니다. 계층적으로 탐색됩니다.
8. 마무리 요약
✅ 자바스크립트 동작 원리의 핵심은 '보이지 않는 흐름'에 있다
자바스크립트를 제대로 이해하려면, 코드 바깥에서 벌어지는 스코프와 실행 컨텍스트의 흐름을 먼저 파악해야 합니다.
코드의 예측 불가능한 동작은 대부분 호이스팅, TDZ, 스코프 체인에서 발생하죠.
렉시컬 스코프 기반의 구조와 호출 스택, 변수 선언의 순서를 파악하면 디버깅 능력도 월등히 올라갑니다.
이론은 어렵지만, 실무에서는 반드시 필요한 개념이니 함수 하나하나의 실행 맥락을 이해하는 연습을 꼭 해보세요!
자바스크립트의 진짜 실력자는, 눈에 보이지 않는 실행 흐름을 읽는 사람입니다.


댓글
댓글 쓰기