클로저(Closer)

📄 클로저란

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

📄 클로저의 동작 원리

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

✔ 결과

2;
3;

inner함수의 실행 시점에는 outer함수가 이미 종료 되었는데 outer함수의 LexicalEnvitonment에 접근했다.

바로 가비지 컬렉터의 동작 방식 때문이다.

가비지 컬렉터는 어떤 값을 참조하는 변수가 하나라도 있다면 그 값은 수집 대상에 포함하지 않는다.

외부함수인 outer의 실행이 종료 되더라도
내부함수인 inner함수는 언젠가 outer2를 실행함으로써 호출될 가능성이 열렸기 때문에
가비지 컬렉터의 수집대상에 포함되지 않는다.

클로저와 메모리 관리

클로저는 어떤 필요에 의해 의도적으로 함수의 지역변수의 메모리를 소모하도록 함으로써 발생한다.

하지만 클로저의 필요성이 사라진 시점에는 더이상 메모리를 소모하지 않게 해주어야 한다.

방법은 참조 카운터를 0으로 만들어 주는 것이다.

식별자에 참조형이 아닌 기본형 데이터(보통null 또는 undefined)를 할당해주면 가비지 컬렉터가 값을 수거해 갈 것이다.

var outer = (function () {
  var a = 1;
  var inner = function () {
    return ++a;
  };
  return inner;
})();
console.log(outer());
console.log(outer());
outer = null; // outer 식별자의 inner 함수 참조를 끊음
(function () {
  var a = 0;
  var intervalId = null;
  var inner = function () {
    if (++a >= 10) {
      clearInterval(intervalId);
      inner = null; // inner 식별자의 함수 참조를 끊음
    }
    console.log(a);
  };
  intervalId = setInterval(inner, 1000);
})();

이렇게 식별자에 기본형 데이터 값을 대입해서 함수 참조를 끊으면 메모리를 효율적으로 관리할 수 있다.

출처

  • 코어 자바스크립트

Leave a comment