자바스크립트 스코프, 실행 컨텍스트, 클로저 그리고 동적 스코프까지 완전 정복

8/3/2025

“이거 딱 한 번만 제대로 이해하면, 자바스크립트 변수/함수 헷갈릴 일 없어요.”

객관식 시험 치듯 ‘스코프란?’ 주입식 설명만 보면 절대 와닿지 않습니다.
여기선 진짜 실제로 많이 틀리는 부분, 복붙해서 바로 실행되는 코드, 실무 팁 위주로 털어봅니다.


📦 스코프(scope): 변수&함수, 어디까지 보이냐의 싸움

👉 1) 전역 스코프 – 언제나 보임

let me = 'whoami';

function cppLecture() {
    console.log(me); // 'whoami' (안에서 바깥 변수 감지 가능)
}

cppLecture();
console.log(me); // 'whoami'

👉 2) 함수(지역) 스코프 – 함수 안에서만 보임

function onlyHere() {
    let hidden = '비밀';
    console.log(hidden); // 정상: '비밀'
}
onlyHere();
// console.log(hidden); // 에러! ReferenceError: hidden is not defined

👉 3) 블록 스코프 (let/const 필수, ES6+)

if (true) {
    let msg = 'hello block';
    console.log(msg); // 정상
}
// console.log(msg); // 에러! ReferenceError

var로 하면 블록 무시하고 탈출(!)함. 그 점 유의!


⛓️ 스코프 체인 – 내부에서 바깥으로 차례대로 찾기

const lang = 'javascript';
function outer() {
    const why = '재밌어서';
        function inner() {
            const job = '프론트엔드';
            console.log(lang); // javascript (전역꺼)
            console.log(why); // 재밌어서 (바깥 함수꺼)
            console.log(job); // 프론트엔드 (자기꺼)
        }
    inner();
}
outer();

값 찾는 순서: 자기 → 바로 바깥 → 쭉쭉 바깥 → 전역 (없으면 에러!)


🧠 렉시컬 스코프 (Lexical Scope)

  • 함수나 변수의 ‘선언 위치’ 기준으로 스코프가 딱! 정해진다
  • 호출 위치? 신경 안 씀.
let who = 'World';
function sayHi() {
    console.log(who);
}
function run() {
    let who = 'JS';
    sayHi(); // 'World'
}
run();

sayHi가 어디서 불렸냐가 아니라, 어디 “정의”됐냐만 따진다!


🏃 실행 컨텍스트 – 실행할 때마다 스택에 쌓임!

“코드 실행할 때 → 실행 컨텍스트(환경정보) 쌓이고 → 끝나면 팝!”

var one = 1;
function outer() {
    var two = 2;
    function inner() {
        var three = 3;
        console.log(one, two, three); // 1 2 3
    }
    inner();
}
outer();
  • 실행 순서:
    1. 전역 컨텍스트(one) 생김
    2. outer() 호출 → outer 컨텍스트(two) push
    3. inner() 호출 → inner 컨텍스트(three) push
    4. inner 끝나면 pop → outer 끝나면 pop → 전역도 eventually pop

👀 변수명이 겹칠 때? (네임 섀도잉!)

const food = '떡볶이';
function eat() {
const food = '김밥';
console.log(food); // 김밥 (더 가까운, 하위 스코프 우선)
}
eat();
console.log(food); // 떡볶이

똑같은 이름 있으면 “내 영역에 제일 가까운 거”부터!


🔥 클로저(Closure): 함수가 바깥 변수까지 ‘기억’하는 현상

function makeCounter() {
    let cnt = 0;
    return function() {
    cnt += 1;
    return cnt;
    }
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

makeCounter() 실행 종료돼도,
안에 있던 cnt가 살아 있어서 계속 접근/변경 가능!
캡슐화, private 변수 쓰고 싶을 때 필수 스킬


🏁 정리표

개념한줄 설명실전 팁
스코프변수·함수가 어디까지 보이냐(접근 가능 범위)“전역/함수/블록/체인” 체감하자
스코프 체인내부→바깥→전역 순서로 찾음클로저에 쓰임, 네임 섀도잉 주의
렉시컬 스코프선언 위치 기준으로 스코프 확정함수 정의 위치만 중요!
실행 컨텍스트실행할 때마다 환경 쌓기(콜스택 구성)함수중첩, 스택 깊이 볼 때 참고
클로저함수가 외부 렉시컬 환경 기억, 참조 가능private 변수, 콜백 로직, 이벤트 핸들러

© 2025 Mingu Kim. All rights reserved.