Skip to main content

Command Palette

Search for a command to run...

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

Published
•3 min read•View as Markdown
렉시컬 스코프(Lexical Scope)란?
D

프론트엔드 개발자 doit입니다.

💡 렉시컬 스코프

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

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

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

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

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

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

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

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. 실행 컨텍스트가 변수를 찾을 때, 렉시컬 스코프를 기반으로 스코프 체인을 탐색!

    • innerVar → inner() 실행 컨텍스트에서 찾음

    • outerVar → outer() 실행 컨텍스트에서 찾음

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

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


✅ 최종 결론

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

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

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

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

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

4 views

More from this blog

Agent Skill로 README 자동화하기

저는 요즘 업무에서 AI 에이전트를 적극적으로 활용하여 반복적인 업무를 최대한 AI로 자동화하기 위해 공부 중인데요. 이번에 했던 작업 중 하나가 README 파일 생성 자동화입니다. AI에게 README를 써달라고 하면 꽤 그럴싸한 결과물이 나옵니다. 하지만 여러 프로젝트에 반복하다 보면 프롬프트가 모호할 때마다 매번 다른 방식으로 문제를 풀기 때문에 들

Mar 31, 20268 min read8

배열을 처리하는 세 가지 방법 (chaining, reduce, for loop)

개발을 하다 보면 배열 데이터를 가공할 일이 정말 많은데요.저는 평소에는 filter, map 같은 메서드 체이닝 방식을 주로 사용합니다. 읽기 쉽고, 데이터 흐름이 단계별로 명확하게 보이기 때문이죠. 하지만 어떠한 계기로(?) 인해 이런 의문을 가지게 되었습니다.. "만약 데이터가 수천만 건으로 늘어난다면? 배열을 여러 번 순회하는 체이닝 방식이 성능 병목을 일으키지는 않을까?" 혹은 "reduce 하나로 합치는 게 베스트일까?" 이 질문을 ...

Feb 4, 20263 min read19

[React] 좋은 추상화란 무엇인가(2) 잘못된 추상화는 중복보다 비싸다

지난 글을 보면 성급했던 재사용 컴포넌트 경험으로 고생을 한 적이 있었는데요.(아직 안 보셨다면? [1편: 좋은 추상화란 무엇인가(1)?] ) 애초에 왜 이런 고생을 했을까를 생각해 보면이유는 단순했습니다. 중복 코드가 거슬리니 바로 추상화를 해버린 것이었죠..똑같은 실수를 반복하지 않기 위해 저만의 기준이 필요하다고 느꼈습니다. 이에 대해 이미 깊이 고민하셨던 Cher Scarlett님과 Kent C. Dodds님의 글을 보면서, 제가 취해야...

Dec 16, 20253 min read25

[React] 좋은 추상화란 무엇인가(1) ? 유연한 컴포넌트 설계를 위한 제어의 역전

재사용을 위해 만든 컴포넌트가, 시간이 지날수록 오히려 재사용하기 어려워진 경험이 있으신가요? 저는 최근 프로젝트에서 SearchFilter 컴포넌트가 그러한데요 프로젝트에는 여러 목록 페이지가 존재했고, 페이지마다 검색 조건이 제각각이었습니다. 그래서 처음에는 Configuration 배열만 넘기면 알아서 그려주는 컴포넌트를 만들었습니다. // ❌ 초기의 설정 기반 접근 (Configuration) const filterFields = [ ...

Dec 9, 202510 min read36

React 시대의 함수형 프로그래밍

바닐라 JS처럼 개발자가 DOM과 상태 변경을 직접 제어하던 시기에는 불변성·순수 함수 같은 함수형 프로그래밍 철학이 지금처럼 중요하지는 않았습니다. 하지만 React(Vue/Redux/SWR/Recoil 등)처럼 선언적·상태 기반 UI가 등장하면서 상태를 “데이터 흐름의 스냅샷”으로 다뤄야 했고, 그때부터 함수형 프로그래밍이 중요해지기 시작했습니다. 🔥 바닐라 JS에서는 왜 FP가 별로 중요하지 않았을까? 바닐라 JS 시대의 UI 개발은...

Dec 8, 20255 min read35
D

Dlog!

39 posts

배우고, 나누며, 함께 성장하는 개발자 🚀