클로저(Closure)
클로저란, 외부함수와 내부함수가 있을 때, 외부함수에 의해 내부함수가 반환된 이후에도, 내부함수에서 외부함수에 있는 변수를 참조할 수 있는 것을 말한다.
조건 3가지
- 외부함수와 내부함수가 존재
- 내부함수가 외부함수에 있는 변수를 참조해야 한다.
- 외부함수가 내부함수를 return(라이프사이클과 관련) 해야한다.
내부함수가 외부함수보다 더 긴 라이프 사이클을 가지고 있을때,
외부함수에 있는 변수를 내부함수가 참조하는데, 그 변수의 값은 유지되어있다.
실행 컨텍스트의 관점에서 이해해보자.
기본적으로 실행 컨텍스트는 함수가 종료되면, 실행 컨텍스트 스택에서 제거된다. 그래서 외부함수에서 내부함수를 반환하고, 모두 실행이 되면, 외부함수의 실행 컨텍스트는 제거된다. 그럼에도 불구하고, 내부함수에서 외부함수의 실행 컨텍스트 내에 있는 활성 객체는 유효하기 때문에, 내부함수에서 외부함수의 변수를 참조할 수 있다. (이때, 이 변수를 자유변수라고 한다.) 이는 내부함수가 스코프 체인을 통해 참조하려는 변수를 먼저 내부함수에서 찾고(내부함수 안에 있는 스코프체인의 ‘0’이 가리키는 활성객체에 참조하려는 변수가 있는지 확인한다.), 없으면, 상위지역인 외부함수에서 찾는다.(내부함수 안에 있는 스코프체인의 ‘1’이 가리키는 활성객체, 즉 외부함수의 활성객체에 들어있는 변수를 말한다.) 이때 내부함수가 외부함수에 있는 변수의 복사본이 아니라, 실제 변수에 접근하는 것이다.
위 내용을 예제와 함께 요약하면 다음과 같다.1
2
3
4
5
6
7
8function outerFunc() {
var x = 10;
var innerFunc = function () { console.log(x); };
return innerFunc;
}
var inner = outerFunc();
inner(); // 10
순서
- 외부함수(outerFunc)가 내부함수(innerFunc)를 반환하고, 외부함수는 종료된다.(이때, 외부함수의 실행 컨텍스트는 실행 컨텍스트 스택에서 제거된다.)
- 내부함수에서 변수 x를 참조하려 할 때, 먼저 내부함수(자기자신) 내에서 그 변수를 찾는다.(내부함수의 스코프체인의 ‘0’이 가리키는 활성객체내에 변수 x를 찾는다.)
- 내부함수내에 없으면, 그 내부함수를 포함하고 있는 외부함수 내에서 그 변수를 찾는다.(내부함수의 스코프체인의 ‘1’이 가리키는 활성객체내에 변수 x를 찾아 참조한다.)
- 이때 내부함수가 외부함수에 있는 변수의 복사본이 아니라, 실제 변수에 접근한다.!