Scoping: 프로그램의 변수가 어디에 있고 어떻게 접근할 수 있는지, 예를 들어 변수가 어디있는지 또는 어디에서 우리가 특정변수에 접근할 수 있고 없는지 정하는 것이다.
Lexical scoping: Scoping은 함수와 블록의 위치에 따라 관리된다. 예를 들어 상위함수에 의해 실행된 함수는 부모의 변수에 접근할 수 있다.
따라서 Variable scoping은 우리가 어떤 블록이나 함수에 코드를 작성하는지에 영향을 받는다.
- Scope: 변수가 선언된 공간이다. 자바스크립트에는 global scope, function scope, block scope가 있다.
- Scope of a variable: 특정 변수에 접근할 수 있는 범위를 말한다.
Global scope
Top -level-code 이다.
어디에서든 접근할 수 있는 변수이다.
const name = 'BoHyeon';
const age = 24;
Function scope
함수 안에서 선언된 변수들
함수 밖에서는 접근할 수 없다.
local scope라고 부르기도 한다.
function calcAge(birthYear){
const nowYear = 2021;
const age = nowYear-birthYear;
return age
}
Block scope
const name = 'BoHyeon';
function first(){
const age = 24;
if(age >= 19){
let upper19 = true;
var isAdult = true;
}
function second(){
const job = 'student'
console.log(`${name} is a ${age}-old ${job}`)
//BoHyeon is a 24-old student
}
second();
}
first();
name = "BoHyeon"
first() scope
age = 24
second() scope
job = "student"
second scope에는 name과 job이 선언 되 있지 않다. 그렇다면 자바스크립트 엔진은 이 변수들에 할당 된 값들을 어떻게 알까?
Scope는 항상 밖의 Scope의 변수에 접근할 수 있다. 즉 부모의 Scope의 변수에 접근할 수 있다.
따라서 second()는 first()와 global scope에 접근 할 수 있고 first()또한 global scope에 접근이 가능하다.
여기에서 보듯이 자신의 scope에 원하는 변수가 없으면 상위 스코프의 변수를 찾아보려고 한다.
위 코드는 다시 다음 처럼 정리 할 수 있다.
name = "BoHyeon"
first() scope
age = 24
name = "BoHyeon" // 자신의 스코프에 없어서 Global scope 참조
second() scope
job = "student"
age = 24 // 자신의 스코프에 없어서 first scope 참조
name = "BoHyeon" // 자신의 스코프에 없어서 Global scope 참조
이같은 과정을 Scope Chain이라고 부른다.
만약 상위 스코프에도 원하는 변수가 없다면 에러가 날 것 이다.
여기서 중요한 것은 이 변수들은 한 스코프에서 다른 스코프로 복사되는 것이 아니다. 그저 Scope chain을 통해 필요한 변수를 찾고 사용하는 것이다.
여기서 들여다 보지 않은 스코프가 하나 있다.
if(age >= 19){
const upper19 = true
var isAdult = true;
}
바로 블록스코프이다.
블록 스코프는 ES6이상에서만 적용된다.
if의 block scope는
upper19 = true
이다.
var로 선언된 변수(isAdult)는 ES6이전의 문법이기 때문에 block scope가 아닌 first() scope, 즉 function scope에 있다.
또 여기서 볼 수 있는 것은 if block scope는 second() scope의 변수에 접근할 수 없고 그 반대도 할 수 없다.