우리가 선언한 변수는 어디에 있는가?
언제 특정 변수에 접근할 수 있는가?
접근 불가능한 경우는 어디에 선언된 어떤 변수인가?
왜 그런 구분이 발생하는가?
위의 질문에 대한 해답으로 JavaScript의 Scope에 대해 알아보도록 하자.
1. Scope의 종류
JavsScript에서는 Scope을 다음의 세 가지로 구분한다: global scope, function scope, block scope
1) Global scope
const name = 'Pride and Prejudice';
const author = 'Jane Austen'
const yearOfPublication = 1813;
- 특정 함수 및 블록 바깥에 선언.
- global scope에 선언된 변수들은 어디서나 접근 가능함.
2) Function scope
const calcBookAge = (yearOfPublication) => {
const now = 2020;
const age = now - yearOfPublication;
return age;
}
console.log(now); // ReferenceError 발생
- 모든 함수는 선언과 함께 해당 함수의 scope이 생성됨.
- 이때, 함수 안에서 선언된 변수들은 해당 함수안에서만 접근 가능.
- global scope의 반대되는 개념으로 local scope이라고도 부름.
3) Block scope (ES6)
if (age >= 50 && age <= 100) {
const classic = true;
}
console.log(classic); // ReferenceError 발생
- 기존에는 함수만 scope을 생성했으나 ES6 이후로 block scope 개념이 추가됨.
- 블록 안에서 선언된 변수는 해당 블록에서만 접근 가능함. (block scope)
- 단, 이는 let이나 const 키워드로 선언된 변수에만 적용되며 var 키워드로 선언된 변수는 여전히 block scope 밖에서 접근 가능함.
- ES6 이후로 모든 function scope은 block scope임.
요약하자면 ES6 이후로 let, const 키워드로 선언된 변수와 함수들은 block scope을 따른다.
2. Scope Chain
다음은 Scope Chain에 대해 알아보자.
const name = 'Pride and Prejudice';
function first() {
const publicationYear = 1813;
if (publicationYear <= 1990) {
const price = 20;
var isClassic = true;
}
function second() {
const author = 'Jane Austen';
console.log( `${name} is written by ${author}, and it costs ${price} dollars`);
}
second();
}
first();
위 코드와 첨부된 사진을 살펴보자.
일단 global scope에는 name 변수가, first() 함수 scope에는 publicationYear 변수가, second() 함수에는 author 변수가 선언되어 해당 scope에 존재함을 알 수 있다.
이때, second() 함수 내부 코드 14줄에서 second() 함수에 선언된 author는 물론 name과 publicationYear 변수에도 접근 가능한 것을 볼 수 있다.
author와 name 변수는 second() 함수 scope 안에서 선언된 변수가 아니지만 JavaScript의 모든 scope은 그 부모(상위) scope의 변수에 접근할 수 있다.
특정 scope 안에서 어떠한 변수를 사용하려 할 때, 해당 변수가 그 scope안에 선언되지 않았을 경우, JavaScript 엔진은 그 상위 scope을 스캔하여 필요한 변수를 찾는다. 이때, 상위 scope에도 찾는 변수가 없으면 global scope까지 계속해서 스캔할 상위 scope를 넓혀가는 데 이를 Scope Chain 이라고 한다.
따라서, Scope Chain에 따르면 앞서 첨부된 사진이 위와 같이 변경된다. 각 scope 별로 상위 scope에 해당하는 변수들을 가지고 있으며 그 변수들에 접근 가능한 것을 확인할 수 있다.
마지막으로 block scope을 살펴보자. if 블록 내부에서 price와 isClassic 두 개의 변수가 선언되었다.
앞서 말했던 것처럼, const 키워드로 선언된 price 변수는 block scope으로 구분되어 first() 함수 scope의 일부로 존재한다.
하지만, var 키워드로 선언된 isClassic은 어떨까? var 키워드로 선언된 변수는 block scope이 아닌 함수 scope으로 존재한다. 즉, if 블록이 아닌 if 블록을 감싸는 함수인 first() 함수의 영역에 존재하여 if 블록 외부에서도 접근 가능하게 된다.
마지막으로, Block scope까지 적용된 scope 별 접근 가능 변수 사진은 다음과 같다.
'JAVASCRIPT' 카테고리의 다른 글
생성자 함수와 Prototype (0) | 2020.11.17 |
---|---|
Closure의 이해 (0) | 2020.11.17 |
this 키워드 (0) | 2020.11.16 |
Hoisting과 Temporal Dead Zone (TDZ) (0) | 2020.11.16 |
Scope와 Call Stack (0) | 2020.11.14 |