우선 Scope에 대해 알아보자.
function outer() {
let a = 1;
console.log(a);
}
outer();
a
에는 무슨 값이 들어있을까 하고 무슨 값이 들어 있는지 찾는 곳이 바로 Scope
다. 일종의 표가 있다고 하자.
위 표가 function outer
의 scope가 된다. 여러 함수가 들어 있다면 scope에 추가 될 것이다.
※ scope는 함수 단위로 적용된다.
예를 들어 outer
함수 내부에 inner
라는 함수를 넣었을 때는 scope
는 어떻게 될까 ?
function outer() {
let a = 1;
function inner() {
let a = 2;
console.log(a);
}
inner();
}
outer();
위 그림 처럼 될 것이다.
inner
가 a를 찾을 때, 들여다보는 표가 바로 scope
이다.
조금 더 나아가보자.
function outer() {
let a = 1;
let b = "영준";
function inner() {
let a = 2;
console.log(b);
}
inner();
}
outer();
outer
안에 b
가 선언되었고, inner
안에서 console.log(b)
를 입력했다.
그러면 inner
는 b
를 어떻게 찾을까?
먼저 그림과 같이
outer
의 scope
에 b가 들어가 있을 것이고, inner
에서는 b
가 없다.
어떻게 b를 찾는지 순서를 보면,
inner
의scope
에서b
가 있는지 찾아본다.b
가 없으니inner
가 태어난 곳 바로 윗단계인outer
에서 찾는다.outer
의scope
에는b
가 있으니,console.log(b)
를 실행.
위 순서대로 scope
를 조사하여 찾는다. 그럼 만약에
let c = "병민";
function outer() {
let a = 1;
let b = "영준";
function inner() {
let a = 2;
console.log(c);
}
inner();
}
outer();
위와 같은 상태면 어떻게 될까 ?? 여기서 c
는 outer
함수안에 있지도 않다.
그림으로 그려보면,
inner scope
-> outer scope
-> global scope
순서대로 찾게 된다.
이렇게 연결된 것이 바로 scope chain
이다.
이제 closure를 살펴보자.
1 let c = "병민";
2
3 function outer() {
4 let a = 1;
5 let b = "영준";
6
7 function inner() {
8 let a = 2;
9 console.log(b);
10 }
11 return inner;
12 }
13 let test = outer();
14 test();
코드해석 : outer()
가 하는 일은 line3 ~ line10
을 지나 line 11
에서 inner
를 return
하고, 그 다음 inner
에서는 line9
에서 console.log(b)
를 실행하는데, 이때 b
는 outer
에 있는 영준
이다.
line13
의test
는outer()
에서inner
를 받게된다.- 그다음, 받게 된
inner
를test()
에서 실행하게 된다.
클로저 설명
outer
의 b
가 사라지는게 아니고, inner
가 b
를 사용할 때에도 scope chain
을 가지고 다닌다. 라는게 closure
이다.
즉, line13
에서 outer()
를 test
라는 이름에 담은 뒤에도, scope chain
이 살아있다.
밖으로 꺼낸 뒤에도, outer 가 실행되고 끝난 뒤에도 scope에 접근할 수 있는 것.