
스코프는 변수(식별자)가 영향을 끼치는 범위를 말한다
let const로 선언된 변수는 블록 스코프를 가진다.var로 선언된 변수는 함수 스코프를 가지기 때문에 블록 바깥까지 영향을 끼친다let x = 1;
{
let x = 2; // 블록 스코프를 가지기 때문에 해당 블록 내부에서만 영향을 준다
}
console.log(x) //1
let은 블록 범위를 가지기 때문에 블록 범위 밖의 식별자에는 영향을 주지 않는다var x = 1;
{
var x =2; // 함수 스코프를 가지기 때문에 블록 외부에도 영향을 준다.
}
console.log(x);
var 변수는 블록문 외부의 식별자에 영향을 끼친다.스코프 체인이란 변수(식별자)를 찾기 위해 내부에서 외부까지 차례대로 검색해나가는 과정이다.
let a = 2;
let b = 3;
function foo(){
let b = 4;
console.log(a); // 2 스코프 체인에 의해 블록문 외부에서 식별자를 가져온다
console.log(b); // 4 가장 가까운 식별자를 찾으면 스코프 체인을 종료한다.
}
foo();
foo() 함수 내부에는 식별자 a가 존재하지 않는다. 하지만 스코프 체인에 의해서 함수 외부에 존재하는 전역 스코프에 선언된 식별자 a를 찾아 사용한다.
foo() 함수 내부와 외부에 모두 동일한 이름의 식별자 b가 존재하는데, conosle.log()가 호출된 가장 가까운 식별자를 찾기 때문에 foo() 함수 내부에 선언된 let b=4 식별자를 사용한다.
스코프 체인을 통해 가져온 외부 식별자를 기억하고 유지하고 있는 함수
function foo(){
let a = 1
return function(){
return ++a
}
}
const bar = foo();
bar() // 2
bar() // 3
a를 증가시킨 후 return한다.a가 존재하지 않기 때문에 스코프 체인 에 의해서 가장 가까운 범위의 식별자 let a=1 를 가져와 사용한다.foo 함수가 종료되었음에도 불구하고 bar 함수는 foo함수에서 선언된 식별자 a 값을 사용하고 있다. 이 때, 식별자 a에는 직접 접근할 수 없다.a 에 대한 참조가 살아있기 때문에 가바지컬렉터는 a메모리를 지우지 않고 있는 상태이다. 이를 클로저 라고 한다.vs let(const)var는 함수 스코프를 가지고 let const는 블록 스코프를 가지기 때문에 변수의 유효범위가 다르다. 함수 스코프를 가진 var를 사용하는경우 블록문 밖과 안에서 선언한 식별자를 중복하여 사용될 경우가 있기 때문에 사용을 지양해야한다.