식별자가 유효한 범위
식별자의 선언 위치에 따라 다른 코드가 식별자를 참조할 수 있는 유효 범위가 결정됨
js 엔진이 식별자를 검색할 때 사용하는 규칙
identifier resolution: js 엔진이 이름이 같은 두 식별자 중 어느 식별자를 참조해야할지 결정하는 것
코드의 문맥context를 고려_코드가 어디서 실행되고 주변에 어떤 코드가 있는지에 따라 동일한 코드도 다른 결과를 만듦
var x = "global";
function foo() {
var x = "local";
console.log(x); // local
}
foo();
console.log(x); // global
스코프 개념이 없으면 위 코드에서 x 변수가 전역, foo 함수 내에 모두 존재해 충돌할 것임
변수는 자신이 선언된 위치에 따라 자신의 스코프가 결정됨 (렉시컬 스코프)
전역에 선언된 변수는 전역 스코프_전역변수 -> 어디서든지 참조 가능
지역에 선언된 변수는 지역 스코프_지역 변수 -> 자신의 지역 스코프, 하위 지역 스코프에서 참조 가능 (함수, 코드블록(let,const))
스코프는 함수의 중첩 의해 계층적 구조
를 가짐
![]() | ![]() |
---|
outer 함수가 만든 지역 스코프는 inner 함수가 만든 지역 스코프의 상위 스코프, outer 함수의 지역 스코프의 상위 스코프는 전역 스코프
-> 모든 지역 스코프의 최상위 스코프는 전역 스코프
변수 참조 시, js 엔진은 변수를 참조하는 코드의 스코프에서 시작해 스코프 체인을 통해 상위 스코프 방향으로 이동하며 선언된 변수를 검색함(identifier resolution)
스코프 체인은 실행 컨텍스트의 렉시컬 환경을 단방향으로 연결한chaining 것임
▫ 스코프 체인에 의한 함수 검색
// 전역 함수
function foo() {
console.log("global function foo");
}
function bar() {
// 중첩 함수
function foo() {
console.log("local function foo");
}
foo(); // local function foo
}
bar();
블록 레벨 스코프 : 모든 코드 블록(함수, if, for, while, try/catch ...) 내에서 선언된 변수는 지역변수로 코드 블록 내에서만 유효함 _const, let
함수 레벨 스코프 : 함수 내에 선언된 변수는 지역변수로 함수 내에서만 유효함, 함수가 아닌 곳에서 선언된 var은 전역변수가 됨
스코프를 결정하는 방식
변수는 선언에 의해 생성
-> 할당을 통해 값을 가짐
-> 언젠가는 소멸
함
변수는 자신이 등록된 스코프가 소멸(메모리 해제)될 때까지 유효함
누군가 스코프를 참조하고 있으면 스코프는 소멸하지 않고 생존하게 됨
변수에 생명 주기가 없다면 한 번 선언된 변수는 프로그램을 종료하지 않는 한 영원히 메모리 공간을 점유함
지역 변수의 생명 주기는 함수의 생명주기와 일치해
함수가 호출돼 실행되는 동안에 유효함 === 지역변수는 지역 스코프를 가짐
function foo() {
var x = 'local';
console.log(x); // local
return x;
}
foo();
console.log(x); // ReferenceError: x is not defined
지역 변수의 호이스팅은 지역 변수의 선언(선언+초기화)이 지역 스코프의 선두로 끌어올려진 것처럼 동작
var x = "global";
function foo() {
console.log(x); // undefined
var x = "local";
}
foo(); // undefined
console.log(x); // "global" 전역변수 x까지는 지역변수의 스코프가 유효하지 않음
var
키워드로 선언한 전역 변수의 생명 주기는 전역 객체의 생명 주기와 일치함
전역 코드는 명시적 호출 없이 로드되자마자 실행되고, 더 이상 실행할 코드가 없으면 종료됨
(function () {
var foo = 100; // 즉시 실행 함수의 지역 변수
// ...
})();
console.log(foo); // ReferenceError: foo is not defined
/**
* Counter 변수에는 즉시 실행함수로 생성된 클래스 느낌의 객체가 값으로 할당되어 있음
* 즉시 실행 함수 내부에서 선언되어 있는 변수는 private 한 성질을 가져, 외부에서 참조 불가능
* 반환하는 public 한 성질의 메서드로 외부에서 특정 기능에만 접근할 수 있게 함
*/
var Counter = (function () {
// private 변수
var num = 0;
// 외부로 공개할 데이터나 메서드 프로퍼티를 추가한 객체를 반환
return {
increase() {
return ++num;
},
decrease() {
return --num;
},
};
})();
console.log(Counter.num); // undefined private 변수는 외부로 노출되지 X
console.log(Counter.increase()); // 1
console.log(Counter.increase()); // 2
console.log(Counter.decrease()); // 1
console.log(Counter.decrease()); // 0
참고 자료