# 클로져(Closure)

함수와 그 함수가 선언될 당시의 환경정보 사이의 조합이라고 설명합니다.

(함수를 선언할 당시의 환경에 함수를 묶어둔 자료구조 => 정적 스코프 static scope 혹은 어휘 스코프 lexical scope)

대체 뭔소린지 알수가 없으므로 아래에서 쉽게 설명합니다.

우선, 함수가 리턴하면 함수내의 변수들은 gc에 의해 사라집니다.

클로저를 사용하면, 최초 선언시의 정보들(참조)을 유지할 수 있습니다.

예를 들면, 함수내에 inner함수를 만들고 outer함수의 변수를 참조하게 만들고 outer함수에서 inner함수를 리턴하게되면

outer함수가 리턴되더라도, outer함수내의 변수가 살아있게 됩니다.

클로저가 형성되면, 그 내부의 환경을 기억하는 것 입니다. => 스코프와 밀접한 관련

(참고 - java언어에서는, final로 선언된 constant만 내부함수에서 참조가 가능하게 되어있습니다.)

아래는 아주 간단한 예제입니다.

function createClosure(v) {
  var v1 = v;
  return function() {
    return v1;
  }
}

var c1 = createClosure(1);
console.log(c1()); //1
var c2 = createClosure('boseok');
console.log(c2()); //"boseok"

이렇게 구현하면 형성된 클로저의 v1변수값을 얻을수있는데,

v1변수를 직접 참조할 수는 없다. => 자바스크립트에서 private 변수를 만드는 방법

# 메모리와 GC

가비지콜렉터가 그 변수를 회수하지않기때문에, 메모리관리에 주의해야한다.

왜 가비지 콜렉터가 그 변수를 회수하지않을까?

직접 접근하지는 못하지만, 닿을 수 있는 오브젝트이기 때문이다.

닿을 수 있는 오브젝트는 gc의 대상이 아니다.

"더 이상 필요없는 오브젝트" == "닿을 수 없는 오브젝트"

아래는 클로저를 이용한 모듈패턴으로,

private변수를 만들수있고, 클로저를 설명하는 대표적인 예시이다.

var counter = (function() { 
  var privateCounter = 0; 
  function changeBy(val) { 
    privateCounter += val; 
  } 
  return { 
    increment: function(val) { 
      changeBy(val); 
    }, 
    value: function() { 
      return privateCounter; 
    } 
  }; 
})();

counter.value(); //0
counter.increment(2);
counter.value(); //2
counter.privateCounter; //undefined

하지만 클로저를 활용하는동안 GC가 메모리를 회수할수없다.

카운터를 만들때마다 각각의 카운터의 인스턴스는 privateCounter를 생성하므로 메모리낭비이다.

그러므로 다 사용하고나면 counter에 null을 대입하여 gc가 작동할수 있도록 해줘야한다.

counter = null;