스코프란?
- 스코프 scope (유효범위): 모든 식별자(변수 이름, 함수 이름, 클래스 이름 등)는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 결정,
- 식별자가 유효한 범위
- 식별자를 검색할 때 사용하는 규칙
- 네임스페이스
- 식별자 결정 identifier resolution: 자바스크립트 엔진이 이름이 같은 두 개의 변수 중에서 어떤 변수를 참조해야할 것인지 결정
- 식별자는 어떤 값을 구별할 수 있으므로 유일 unique 해야함, 즉 하나의 값은 유일한 식별자에 연결 name binding 되어야 함
var var1 = 1; // 코드의 가장 바깥에서 선언한 변수
if (true) {
var var2 = 2; // 코드 블록 내에서 선언한 변수
if (true) {
var var3 = 3; // 중첩된 코드 블록 내에서 선언한 변수
}
}
function foo() {
var var4 = 4; // 함수 내에서 선언한 변수
function bar() {
var var5 = 5; // 중첩된 함수 내에서 선언한 변수
}
}
console.log(var1); // 1
console.log(var2); // 2
console.log(var3); // 3
console.log(var4); // ReferenceError: var4 is not defined
console.log(var5); // ReferenceError: var5 is not defined
var x = "global";
function foo() {
var x = "local";
console.log(x);
}
foo();
console.log(x);
스코프의 종류
- 코드는 전역 global과 지역 local으로 구분
- 변수는 자신이 선언된 위치(전역 또는 지역)에 의해 자신이 유효한 범위인 스코프가 결정
구분 | 설명 | 스코프 | 변수 |
전역 | 코드의 가장 바깥 영역 | 전역 스코프 | 전역 변수 |
지역 | 함수 몸체 내부 | 지역 스코프 | 지역 변수 |
전역과 전역 스코프
- 전역이란 코드의 가장 바깥 영역을 의미
- 전역은 전역 스코프 global scope를 만듦
- 전역에 변수를 선언하면 전역 스코프를 갖는 전역 변수 global variable이 됨
- 전역 변수는 어디서든지 참조할 수 있음
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(y); // global y
console.log(z); // ReferenceError: z is not defined
지역과 지역 스코프
- 지역이란 함수 몸체 내부
- 지역은 지역 스코프 local scope를 만듦
- 지역에 변수를 선언하면 지역 스코프를 갖는 지역 변수 local variable이 됨
- 지역 변수는 자신의 지역 스코프와 하위 지역 스코프에서 유효
스코프 체인
- 스코프가 함수의 중첩에 의해 계층적 구조를 갖음
- 스코프 체인 scope chain: 모든 스코프가 계층적 구조로 연결
- 변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색 identifier resolution
- 스코프 체인은 물리적인 실체로 존재하며, 렉시컬 환경 Lexical Environment를 실제로 생성
- 변수 선언이 실행되면 변수 식별자가 렉시컬 환경에 키 key로 등록되고, 변수 할당이 일어나면 변수 식별자에 해당하는 값을 변경
스코프 체인에 의한 변수 검색
- 자바스크립트 엔진은 스코프 체인을 따라 변수를 참조하는 코드의 스코프에서 시작해서 사위 스코프 방향으로 이동하며 선언된 변수를 검색
- 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조 가능
- 하위 스코프에서 유효한 변수를 상위 스코프에서는 참조할 수 없음
스코프 체인에 의한 함수 검색
- 함수도 식별자에 해당되기 때문에 스코프를 갖음
- 함수는 식별자에 함수 객체가 할당된 것 외에는 일반 변수와 다를 바 없음
함수 레벨 스코프
- 블록 레벨 스코프 block level scope: 모든 코드 블록 (if, for, while, try/catch emd)이 지역 스코프를 만듦 (대부분의 프로그래밍 언어; C, 자바)
- 함수 레벨 스코프 function level scope: 오로지 함수 코드 블록 (함수 몸체)만을 지역 스코프로 인정 ( var 키워드로 선언된 변수)
- ES6에서 도입된 let, const 키워드는 블록 레벨 스코프를 지원
렉시컬 스코프
- 동적 스코프 dynamic scope: 함수를 어디서 호출했는지에 따라 함수의 상위 스코프 결정
- 렉시컬 스코프 lexical scope 혹은 정적 스코프 static scope: 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정
- 자바스크립트는 렉시컬 스코프를 따름
- 함수의 상위 스코프는 함수 정의가 실행될 때 정적으로 결정되며, 생성된 객체는 이렇게 결정된 상위 스코프를 기억함
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x);
}
foo(); // 1
bar(); // 1
// foo 내부에서 호출한 bar는 전역 스코프에서 정의되었기 때문에
// bar가 호출될 때 전역 스코프의 x를 참조함
'Javascript > 모던 자바스크립트 DeepDive' 카테고리의 다른 글
[모던 자바스크립트 Deep Dive] 15 let, const 키워드와 블록 레벨 스코프 (0) | 2023.12.12 |
---|---|
[모던 자바스크립트 Deep Dive] 14 전역 변수의 문제점 (1) | 2023.12.11 |
[모던 자바스크립트 Deep Dive] 12 함수 (0) | 2023.12.11 |
[모던 자바스크립트 Deep Dive] 11 원시 값과 객체의 비교 (0) | 2023.12.11 |
[모던 자바스크립트 Deep Dive] 10 객체 리터럴 (1) | 2023.12.10 |