MDN : Closure : 결합 조합 조화
클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.
어휘적 환경 == 렉시컬 환경
렉시컬 환경의 조합이란 무엇일까요?
컨텍스트 A가 있고 내부함수 B가 있습니다.
컨텍스트 A의 enviromentRecord( 내부환경 ) 에는 함수 B가 있습니다.
내부함수 B의 outerEnviromentReference( 외부환경 참조 ) 에는 컨텍스트 A의 enviromentRecord( 내부환경 ) 가 있습니다.즉, 자바스크립트에서 함수는 부모 함수의 정보를 가지고있다는 뜻이죠. 우리가 부모님의 눈,코,입,나이,생일 등을 알고있듯이 상속의 개념과 유사하다고 생각됩니다.
클로저는 함수가 생성되면 언제나 발생하는 현상입니다. 하지만 우리가 말하는 클로저는 이런 보편적인 상황에 모두 적용해서 사용하는 것은 아닙니다.자바스크립트 개발환경에서의 클로저란, "둘러쌓인 렉시컬환경의 참조" 에서 발생하는 "특별한 현상" 입니다.
그럼 특별한 현상이란 무엇일까요?
var outer = function () {// 전역 컨텍스트 - outer컨텍스트 클로저발생 : outer도 전역객체의 정보를 가지고있지만,
var x=1; //참조한 변수,함수 등이 없기에 평범한 클로저 입니다.
var inner =function () { //outer - inner : inner에서 outer의 a참조 특별한 클로저 발생
return ++x;
}
return inner;
}
>
var closure = outer();
console.log(closure()); //2
console.log(closure()); //3
위와 같은 상황에서 특별한 현상이 나타나게 됩니다.
자, 우리는 inner 함수가 outerEnviromentReference( 외부환경참조 ) 에 outer 함수의 enviromentRecord( 환경정보 )를 가지고 있다는것을 알고있죠. 그것은 변수 x 도 가지고 있다는 뜻입니다.
outer() 의 결과 값은 무엇일까요? inner 함수를 리턴하고 있습니다.
var inner = function () { return ++x; }
위와 같습니다.
그렇다면, closure함수는 변수는 outer 함수의 a변수를 참조하고있죠?
어떤가요? 지역변수는 일반적인 경우에서 실행컨텍스트가 닫히면 참조카운트가 0 이 되기때문에 가비지컬렉터의 대상이 됩니다.
변수 x의 참조 카운트가 0 이 아니기 때문에 소멸하지 않고 여전히 메모리에 존재하고 있다는 겁니다.
이러한 상황을 클로저를 이용했다고 합니다.
a의 참조카운트를 0으로 만드는 방법은 closure 변수에 다른 값을 할당하는 방법이 있습니다.
클로저 한마디 요약
컨텍스트 A가 있고 내부함수 B가 있다는 가정
컨텍스트 A에서 선언한 변수 x를 참조하는 내부함수 B를 A의 외부로 전달할 경우, A컨텍스트가 종료되어도 지역변수 x가 소멸되지 않는 특별한 현상이 클로저의 핵심 입니다.