렉시컬 스코프(Lexical Scope)란?

렉시컬 스코프(Lexical Scope)란?

·

3 min read

💡 렉시컬 스코프

자바스크립트에서 헷갈리는 부분이
“자바스크립트는 동적 언어이지만, 스코프 결정 방식은 "정적"으로 동작한다”
즉, 변수의 타입은 실행 시점에 결정되지만(=동적), 스코프는 선언된 위치에서 결정된다(=정적)

🔍자바스크립트는 동적언어인데, 스코프는 어떻게 정적으로 결정될까?

자바스크립트는 동적 언어이지만 동시에 렉시컬 스코프를 사용하는 언어이기 때문이다.

렉시컬 스코프란 함수가 선언된 위치에 따라 해당 함수가 접근할 수 있는 변수의 범위(스코프)가 결정되는 방식이다.

  • 함수가 어디서 "실행"되었는지가 아니라, 어디서 "선언"되었는지에 따라 스코프가 결정됨

  • 즉, 함수를 감싸고 있는 블록(또는 함수)의 스코프를 따라감

  • 함수가 실행될 때마다 새로운 실행 컨텍스트가 만들어지지만, 렉시컬 스코프는 변하지 않음

const x = 1;
function foo() {
    const x = 10;
    bar();
}
function bar() {
    console.log(x);
}
foo();
bar();
  1. bar() 함수는 전역에서 선언 되었으므로, 전역 스코프를 따름.

  2. bar() 내부에서 x를 찾을 때, 전역 x = 1을 참조함.

  3. foo() 내부에서 실행되었어도, bar()의 스코프는 변하지 않는다!

🚀 즉, "선언된 위치"를 기준으로 스코프가 결정된다!
🚀 자바스크립트는 실행 위치가 아니라 선언 위치를 기준으로 변수를 찾는다!


💡 실행 컨텍스트 vs 렉시컬 스코프

자바스크립트를 제대로 이해하려면 "렉시컬 스코프(Lexical Scope)" 와 **"실행 컨텍스트(Execution Context)"**를 정확히 아는 것이 중요하다

실행 컨텍스트 vs 렉시컬 스코프 개념 정리

  • 렉시컬 스코프 (Lexical Scope): 함수가 선언된 위치를 기준으로 스코프가 결정되는 규칙

  • 실행 컨텍스트 (Execution Context): 코드가 실행될 때 생성되는 실행 환경(변수, 스코프, this 등을 저장하는 객체)

즉, 실행 컨텍스트는 "실행될 때" 만들어지는 개념이고, 렉시컬 스코프는 "코드가 작성될 때" 이미 정해지는 개념이다!

실행 컨텍스트 vs 렉시컬 스코프 비교

📌 렉시컬 스코프 원리

  • 함수가 어디서 실행되었는지가 아니라, 어디서 "선언"되었는지를 기준으로 스코프가 결정됨.

  • 코드를 작성할 때(정적, Static) 이미 스코프 체인이 형성됨.

  • 실행할 때마다 스코프 체인이 변하지 않음.

📌 실행 컨텍스트 원리

  • 코드가 실행될 때, 실행 컨텍스트가 생성됨.

  • 실행 컨텍스트는 현재 실행 중인 코드에 대한 정보(변수, 스코프, this)를 저장하는 객체임

  • 콜 스택(Call Stack)에 쌓였다가, 실행이 끝나면 제거됨.

🚀 즉, 실행 컨텍스트는 "현재 실행 중인 코드의 실행 환경"을 저장하는 개념이다!
🚀 함수가 실행되면 실행 컨텍스트가 생기고, 실행이 끝나면 콜 스택에서 제거된다!


실행 컨텍스트가 렉시컬 스코프를 참고하는 과정

실행 컨텍스트가 변수를 찾을 때, 렉시컬 스코프를 기반으로 스코프 체인을 사용하여 변수를 조회한다!

javascript복사편집const globalVar = "I am global";

function outer() {
    const outerVar = "I am outer";

    function inner() {
        const innerVar = "I am inner";
        console.log(globalVar); // 🔥 전역에서 찾음
        console.log(outerVar);  // 🔥 outer()에서 찾음
        console.log(innerVar);  // 🔥 inner()에서 찾음
    }

    return inner;
}

const myFunc = outer(); // outer 실행 후 inner 반환
myFunc(); // inner() 실행
  1. outer() 실행 → 실행 컨텍스트 생성

  2. inner() 실행 → 실행 컨텍스트 생성

  3. 실행 컨텍스트가 변수를 찾을 때, 렉시컬 스코프를 기반으로 스코프 체인을 탐색!

    • innerVarinner() 실행 컨텍스트에서 찾음

    • outerVarouter() 실행 컨텍스트에서 찾음

    • globalVar → 전역 실행 컨텍스트에서 찾음

🚀 즉, 실행 컨텍스트는 "현재 실행 중인 환경"을 저장하지만, 변수를 찾을 때는 렉시컬 스코프(선언된 위치)를 따른다! 🚀


최종 결론

"렉시컬 스코프는 코드가 작성될 때(정적) 스코프를 결정하는 규칙이고, 실행 컨텍스트는 코드가 실행될 때(동적) 생성되는 실행 환경이다!" 🚀

📌 정리하면?
렉시컬 스코프"함수가 선언된 위치를 기준으로 변수를 찾음" (정적)
실행 컨텍스트"현재 실행 중인 코드의 실행 환경을 저장하고 관리함" (동적)

  • 실행 컨텍스트가 생성될 때, 함수가 선언된 위치(렉시컬 스코프)를 기준으로 OuterEnvironmentReference가 설정된다.

  • 실행 컨텍스트가 변수를 찾을 때, EnvironmentRecord에서 먼저 찾고 없으면 OuterEnvironmentReference를 따라 상위 컨텍스트로 이동하여 계속 검색한다

  • 최종적으로 전역 컨텍스트까지 가도 변수를 찾지 못하면 ReferenceError가 발생한다