클로저란
- 어떤 함수 A에서 선언 한 변수 a를 참조하는 내부함수 B를 외부로 전달할 경우 A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상이다.
- 변수 a를 참조하는 내부함수가 외부로 전달될 경우 함수 A의 실행 컨텍스트가 종료된 후에도 변수 a가 가비지 컬렉터의 수집 대상에서 제외된다. → 내부 함수 B가 변수 a에 접근할 수 있다.
예시1)
const outer = function () {
const a = 1;
const inner function () {
return ++a;
};
return inner;
};
const outer2 = outer();
console.loog(outger2()); // 2
console.log(outer2()); // 3
outer2 = null;
- 내부 함수가 외부로 전달되는 것이 곧 return만을 의미하는 것은 아니다.
return 없이도 클로저가 발생하는 다양한 경우
예시2)
// setInterval/setTimeOut
(function () {
const a = 0;
const intervalId = null;
const inner = function () {
if (++a >= 10) {
clearInterval(intervalId);
inner = null;
}
console.log(a);
};
intervalId = setInterval(inner, 1000);
})();
- 별도의 외부 객체인 window의 메서드(setTimeout or setInterval)에 전달할 콜백 함수 내부에서 지역변수를 참조
예시3)
// eventListener
(function () {
const count = 0;
const button = document.createElement("button");
button.innerText = "click";
button.addEventListener("click", function () {
console.log(++count, "times clicked");
if (count >= 10) {
button.removeEventListener("click", clickHandler);
}
});
document.body.appendChild(button);
})();
- 별도의 외부객체인 DOM의 메서드(addEventListener)에 등록할 handler 함수 내부에서 지역변수를 참조
클로저와 메모리 관리
- 클로저는 어떤 필요에 의해 의도적으로 함수의 지역변수를 메모리를 소모하도록 함으로써 발생 → 그 필요성이 사라진 시점에는 더는 메모리를 소모하지 않게 하여 관리 가능