<aside> ❓

모든 식별자(변수 이름, 함수 이름, 클래스 이름 등)는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 결정된다.

이를 스코프라고 한다.

즉, 식별자가 유효한 범위를 말한다.

</aside>

✏️

var x = 'global';

function foo() {
	var x = 'local;
	console.log(x); // 'local'
}

foo();

console.log(x) // 'global'

자바스크립트 엔진은 이름이 같은 두 개의 변수 중에서 어떤 변수를 참조해야 할 것인지 결정해야한다.

이를 “식별자 결정”이라고 한다.

자바스크립트 엔진은 스코프를 통해 어떤 변수를 참조해야할 것인지 결정한다.

따라서 스코프란 자바스크립트 엔진이 식별자를 검색할 때 사용하는 규칙이라고도 할 수 있다.

<aside> ❓

렉시컬 환경(lexical environment)

코드가 어디서 실행되며 주변에 어떤 코드가 있는지를 부르는 말

즉, 코드의 문맥(context)은 렉시컬 환경으로 이루어진다.

모든 코드는 ‘실행 컨텍스트(execution context)’에서 평가되고 실행된다.

변수와 함수가 선언된 위치를 기준으로 스코프를 정의하고, 이를 참조할 수 있도록 구성한 환경

자바스크립트에서 코드가 실행되기 전에 변수나 함수의 선언위치에 따라 스코프가 결정되고, 실행 시점에 이를 추적할 수 있도록 메모를 구조를 생성하는데 이것이 렉시컬 환경의 생성이다.

</aside>

❌ var 키워드로 선언한 변수의 중복 선언

//var
function foo() {
	var x = 1;
	var x = 2;
	console.log(x); // 2
}
foo();

//let
function bar() {
	let x = 1;
	let x = 2; // SyntaxError: Identifier 'x' has already been declared
}
bar();

var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언이 허용된다.

이는 의도치 않게 변수 값이 재할당되어 변경되는 부작용을 발생시킨다.

하지만, let이나 const 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용하지 않는다.

스코프 내에서 식별자는 유일해야 하지만 다른 스코프에는 같은 이름의 식별자를 사용할 수 있다.

즉, 스코프는 ‘네임스페이스’이다.

스코프의 종류