스코프 체인
자바스크립트는 스코프라는 개념이 있다.
스코프는 유효범위를 뜻하고, 크게는 함수 레벨 스코프와 블록 레벨 스코프가 있다.
var로 선언한 변수는 함수 레벨 스코프를 따르는데, var은 옛 것이므로 생략하면 let과 const는 블록 레벨 스코프를 따른다.
이 때 블록은 {}를 뜻한다.
따라서 자바스크립트는 {}안에서만 같은 레벨인 것이다.
하지만 같은 스코프 안의 변수만을 사용할 수는 없다.
이 때 필요한 것이 스코프 체인이다.
스코프 체인은 하위 스코프가 상위 스코프를 참조하는 것을 의미한다.
const a = 10;
{
console.log(a); // 10
}
콘솔이 찍히는 곳은 글로벌 안의 하위 스코프지만, 해당 스코프에 a가 선언되어 있지 않으므로 상위 스코프에서 a를 가져온다.
const a = 10;
{
const a = 5;
console.log(a); // 5
}
물론 해당 스코프에 a가 선언되어 있다면 해당 스코프에서 선언된 변수를 사용한다.
const a = 10;
function addTen(num) {
console.log(a + num);
}
addTen(30); // 40
이를 이용하면 함수 바깥에서 선언된 변수를 가져와 함수에서 사용할 수도 있다.
만약 함수가 2중으로 있는 형태에서는 아래와 같이 작동한다.
const a = 10;
function outer() {
const a = 50;
function inner() {
const b = 3;
console.log(a); // 50
console.log(b); // 3
}
inner();
}
outer();
inner 함수에서 호출한 변수a는 바로 상위 블록인 outer에서 탐색하고 outer에 a가 있기 때문에 이를 호출한다.
이를 그림으로 표현하면 다음과 같다.
호출이 되는 스코프를 기준으로 만약 변수가 있다면 해당 스코프에서 호출하고 (예제에서의 b) 만약 존재하지 않으면 바로 상위 스코프를 참조한다.
해당 경우에서는 변수 a가 inner에 없기 때문에 상위 스코프인 outer에서 확인하고 outer에 있기 때문에 outer스코프에서 a를 호출하게 된다.
만약 outer에도 없다면 global에서 호출하게 될 것이다.
이런 스코프 체인을 이용하면 클로저를 사용할 수 있다.
클로저
클로저는 함수와 렉시컬 환경의 조합이다.
렉시컬 환경을 블럭으로 생각하면 함수는 그에 맞는 블록 레벨이 존재하는데, 해당 함수를 변수로 지정하면 함수뿐 아니라 그에 해당하는 스코프까지 변수로 저장이된다.
function outer() {
const a = 50;
return function inner(b) {
return a + b;
};
}
const closure1 = outer();
console.log(closure1(3)); // 53
위 예제는 inner를 리턴하는 outer함수의 예시이다.
closure1에 outer를 저장하면, 아우터의 스코프자체도 closure1에 저장된다.
function outer(a) {
return function inner(b) {
return a + b;
};
}
const closure10 = outer(10);
const closure100 = outer(100);
console.log(closure10(3)); // 13
console.log(closure10(15)); // 25
console.log(closure100(3)); // 103
console.log(closure100(15)); // 115
위 예제에서 closure10과 closure100은 같은 함수를 호출했으나 outer의 argument가 다르다.
따라서 이 둘은 서로 다른 렉시컬 환경을 갖는다.
따라서 위와 같은 환경을 closure10, closure100에 따로 저장하고 있고 이를 클로저라고한다.
클로저를 사용하면 외부의 영향을 받지 않는 은닉 변수를 사용할 수 있다.
위의 예제에서 closure10의 a = 10은 더 이상 변경할 수 없는 은닉 변수가 되는 것이다.
출처 : https://www.youtube.com/watch?v=MbYShFxp-j0&t=128s&ab_channel=%EC%BD%94%EB%93%9C%EC%A2%85
'Languages > Javascript' 카테고리의 다른 글
JS에서 string을 number로 바꾸는 방법들 (0) | 2022.05.06 |
---|---|
Javascript-1d or 2d array 간단히 만들기 (0) | 2021.12.03 |
Javascript-map (0) | 2021.11.20 |
Javascript-reduce (0) | 2021.11.09 |