index
1. 스코프(Scope)의 정의
모든 식별자(변수 이름, 함수 이름, 클래스 이름 등)는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효범위가 결정된다. 이를 스코프라 한다. 즉, 스코프는 식별자가 유효한 범위를 말한다.
🤓 코드의 문맥과 환경
렉시컬 환경(Lexical Environment): 코드가 작성된 위치에 따라 변수가 어떻게 연결되고, 어떤 스코프에서 유효한지를 결정한다.
실행 컨텍스트(execution context) : 자바스크립트 코드가 실행되는 환경을 말하며, 코드가 실행될 때마다 자바스크립트 엔진은 실행 컨텍스트를 생성하고, 그 안에서 모든 코드 실행이 이루어진다.
🧐 Q. var는 변수의 중복선언이 가능하나 let, const는 변수의 중복선언이 불가능한 이유는 무엇일까?
var의 중복선언 변론, 초기 설계는 단순성과 유연성에 중점
var
의 중복 선언을 허용한 이유는 개발자가 변수를 재사용하는 데 있어 더 자유롭게 할 수 있도록 하기 위한 의도입니다. 중복 선언을 허용하면, 다른 코드에서 같은 이름으로 변수를 다시 선언해도 문제가 발생하지 않습니다. 대신, 중복 선언된 경우에는 값을 덮어씌우는 방식으로 처리합니다.
VS
let, cost의 중복선언 불가 변론, 코드의 명확성과 안정성에 중점
let
과 const
의 설계 철학은 변수 선언이 명확해야 하고, 중복 선언으로 인한 의도치 않은 오류를 방지해야 한다는 것입니다. 변수를 중복 선언하는 것은 코드의 가독성을 떨어뜨리고, 값이 덮어씌워지는 문제로 이어질 수 있습니다. 따라서 let
과 const
는 중복 선언을 명시적으로 금지함으로써 보다 명확하고 예측 가능한 코드 작성을 유도합니다.
2. 스코프 체인(scope chain)

Scope
Jay Tak.
var x = "global x";
var y = "global y";
function outer() {
var z = "outer's local z";
console.log(x); // global x
console.log(y); // global y
console.log(z); // outer's local z
function inner() {
var x = "inner's local x";
console.log(x); // inner's local x
console.log(y); // global y
console.log(z); // outer's local z
}
inner();
}
outer();
console.log(x); // global x
console.log(z); // ReferrenceError: z is not defined
자바스크립트 엔진은 스코프 체인을 따라 변수를 참조하는 코드의 스코프에서 시작해서 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다. 절대 하위 스코프로 내려가면서 식별자를 검색하는 일은 없다. 이는 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조할 수 있지만 하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수 없다는 것을 의미한다.
스코프 체인으로 연결된 스코프의 계층적 구조는 부자 관계로 이뤄진 상속(inheritance)과 유사하다. 상속을 통해 부모의 자산을 자식이 자유롭게 사용할 수 있지만 자식의 자산을 부모가 사용할 수는 없다. 스코프 체인도 마찬가지 개념이다.
3. 렉시컬 스코프(Lexical scope)
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x);
}
foo(); // 1
bar(); // 1
위 예제가 시사하는 바는 bar 함수의 상위스코프가 무엇인지 묻고 있다. 두가지 경우를 생각해볼 수 있다.
- 함수를 어디서 호출했는지에 따라 함수의 상위 스코프가 결정한다. => ‘동적 스코프’
- 함수를 어디서 정의했는지에 따라 함수의 상위 스코프가 결정한다. => ‘렉시컬 스코프’
자바스크립트는 렉시컬 스코프를 따르므로 (함수를 어디서 호출했는지가 아니라) 함수를 어디서 정의했는지에 따라 상위 스코프가 결정한다. 함수가 호출된 위치는 상위 스코프 결정에 어떠한 영향도 주지 않는다. 즉, 함수의 상위 스코프는 언제나 자신이 정의된 스코프다.
bar 함수는 전역에서 정의된 함수다. 함수 선언문으로 정의된 bar 함수는 전역 코드가 실행되기 전에 먼저 평가되어 함수 객체를 생성한다. 이때 생성된 bar 함수 객체는 자신이 정의된 스코프, 즉 전역 스코프를 기억한다. bar 함수가 호출된 곳이 어디인지 관계없이 자신이 기억하고 있는 전역 스코프를 상위스코프로 사용한다.
🧐 Core Insight!
“A Closer is the combination of a function and the lexical environment within which that function was declared.”
“클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.”