스코프(scope) = 유효범위: 식별자가 유효한 범위
⇒ 모든 식별자(변수 이름, 함수 이름, 클래스 이름 등)는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 결정됨
function add(x, y) {
// 매개변수는 함수 몸체 내부에서만 참조 가능
// 즉, 매개변수의 스코프(유효범위)는 함수 몸체 내부
console.log(x, y);
return x + y;
}
add(2, 5);
// 매개변수는 함수 몸체 내부에서만 참조 가능
console.log(x, y); // ReferenceError: x is not defined
렉시컬 환경: 코드가 어디서 실행되며 주변에 어떤 코드가 있는지
“코드의 문맥”
은 렉시컬 환경으로 이뤄짐- 이를 구현한 것이 “실행 컨텍스트”임
- 모든 코드는 실행 컨텍스트에서 평가되고 실행됨
var x = "global";
function foo() {
var x = "local";
console.log(x); // local
}
foo();
console.log(x); // global
var
키워드로 선언된 변수는 같은 스코프 내에서 중복 선언 허용 → 의도치 않게 변수값이 재할당됨function foo() {
var x = 1;
// var 키워드로 선언된 변수는 같은 스코프 내에서 중복 선언 허용
// 아래 변수 선언문은 자바스크립트 엔진에 의해 var 키워드가 없는 것처럼 동작
var x = 2;
console.log(x); // 2
}
foo();
function bar() {
let x = 1;
// let, const 키워드러 선언한 변수는 같은 스코프 내에서 중복 선언 허용 X
let x = 2; // SyntaxError: Identifier 'x' has already been declared
}
bar();
구분 | 설명 | 스코프 | 변수 |
---|---|---|---|
전역 | 코드의 가장 바깥 영역 | 전역 스코프 | 전역 변수 |
지역 | 함수 몸체 내부 | 지역 스코프 | 지역 변수 |
전역: 코드의 가장 바깥 영역 → 전역 스코프를 만듦
지역: 함수 몸체 내부 → 지역 스코프를 만듦
함수의 중첩: 함수 몸체 내부에서 함수가 정의된 것
⇒ 스코프가 함수의 중첩에 의해 계층적 구조를 가짐
❗️렉시컬 환경(Lexical Environment)
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); // ⑧ ReferenceError: z is not defined
a. ④ x 변수 참조하는 코드의 스코프 inner 함수의 지역 스코프에서 x 변수가 선언되었는지 검색
b. inner 함수 내에 x 변수가 선언되어 있으므로 var x = "inner's local x";
검색된 변수 참조후 검색 종료
a. ⑤ y 변수 참조하는 코드의 스코프인 inner 함수의 지역 스코프에서 y 변수가 선언되었는지 검색
b. inner 함수 내에 선언된 y 변수가 없으므로 상위 스코프인 outer 함수의 지역 스코프로 이동하여 y 변수 검색
c. outer 함수의 지역 스코프 안에서도 y 변수가 선언되지 않았으므로, 또 다시 상위 스코프인 전역 스코프로 이동하여 검색
d. 전역 스코프에 y 변수가 선언되어있으므로 해당 변수 참조하고 검색 종료
a. ⑥ z 변수를 참조하는 코드의 스코프인 inner 함수의 지역 스코프에서 z 변수가 선언되었는지 검색
b. inner 함수 내에 선언된 z 변수가 없으므로 상위 스코프인 outer 함수의 지역 스코프로 이동하여 z 변수 검색
c. outer 함수의 지역 스코프 내에 선언된 z 변수가 있으므로 해당 변수 참조 후 검색 종료
// 전역 변수
function foo() {
console.log("global function foo");
}
function bar() {
// 중첩 함수
function foo() {
console.log("local function foo");
}
foo(); // ①
}
bar();
var
키워드로 선언된 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정 ⇒ 함수 레벨 스코프var x = 1;
if (true) {
// var 키워드로 선언된 변수는 함수의 코드 블록만을 지역 스코프로 인정
// 함수 밖에서 var 키워드로 선언된 변수는 코드 블록 내에서 선언되었어도 모두 전역 변수임
var x = 10;
}
console.log(x); // 10
var x = 1;
function foo() {
var x = 0;
bar();
}
function bar() {
console.log(x);
}
foo();
bar();
// 1
// 1