클로저

<aside> 💡 클로저란 어떤 함수 A에서 선언한 변수 a를 참조하는 내부함수 B를 전달할 경우 A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상

</aside>

클로저의 정의들

MDN에서는 클로저에 대해 다음과 같이 설명하고 있다.

클로저는 함수와 그 함수가 선언될 당시의 lexical environment의 상호관계에 따른 현상

이때 선언될 당시의 L.E는 실행 컨텍스트의 구성요소인 outerEnvironmentReference에 해당한다.

외부 함수의 변수를 참조하는 내부 변수

var outer = function () {
	var  a = 1;
	var inner = function() {
		return ++a;
	}
	return inner();
};
var outer2 = outer();
console.log(outer2);

inner 함수 내부에서는 외부변수인 a를 사용하고 있다. 그런데 outer함수는 inner 함수를 실행한 결과를 리턴하고 있으므로 결과적으로 outer 함수의 실행 컨텍스트가 조료된 시점에는 a변수를 참조하는 대상이 없어진다. 그러므로 inner 변수의 값들은 언젠가 가비지 컬렉터에 의해 소멸한다.

var outer = function () {
	var  a = 1;
	var inner = function() {
		return ++a;
	}
	return inner;
};
var outer2 = outer();
console.log(outer2());

함수 자체를 반환하면, outer함수의 실행 컨텍스트가 종료될때 outer2 변수는 outer의 실행 결과인 inner함수를 참조한다. 이후 outer2를 실행하면 앞서 반환된 inner가 실행된다.

위 코드는 아래와 같은 방식으로 작동된다.

  1. inner 함수의 실행 컨텍스트의 environmentRecord는 수집할 정보가 없다.
  2. outer-EnvironmentReference에는 inner 함수가 선언된 위치의 LE가 참조복사된다.
  3. inner 함수는 outer 함수 내부에서 선언됐으므로, outer함수의 LE가 담긴다.
  4. 이제 스코프 체이닝에 따라 outer에서 선언한 변수 a에 접근해서 1만큼 증가시킨후 값을 반환한다.
  5. inner 실행 컨텍스트 종료