2015년 6월 7일 일요일

Javascript closure의 이해

다음의 Javascript 구현은 local 변수의 값을 return하는 것이다.
function testNoClosure(){
    var a = 100;
    return a;
}
console.log(testNoClosure()); //100을 출력

당연하게도 그 local변수에 직접 접근하는 방법은 없다.
예를 들어 다음과 같이 local변수를 접근하려 하면 'ReferenceError: a is not defined'가 발생한다.
console.log(a);

즉, local변수는 함수 scope내에서만 유효하고 다른 scope에서는 유효하지 않다.

Closure는 이런 제약을 없애는 것으로, 필요한 variable을 binding해서 다른 scope에서도 참조할 수 있도록 한 것이다.
다음의 구현을 보자.
function testClosure(){
    var a = 100;
    function f(){
        return a;
    }
    return f;
}
var checkLocalA = testClosure();
console.log(checkLocalA());

위에서 inner function인 f는 outer function의 변수인 a를 마치 'global' 변수처럼 access한다. parameter로 넘길 필요도 없고, 따로 함수내부의 다른 변수에 값을 저장할 필요도 없다. 그렇지만, inner function이 호출되는 시점(위에서는 console.log(checkLocalA()))에 outer function의 변수 a에 접근할 수 있는 것이다.


여기까지만 이야기 하면 어떻게 쓸지 잘 감이 안온다. 실제 사용예를 보자.
function makeTransport(kind){
    var count = 0;
    return function(brand) {
        count++;
        console.log("Kind: " + kind + ", brand: " + brand + " - " + count);
    }
}
var getCar = makeTransport("Car");
getCar("Bentz");
getCar("Hyundai");
var getAirplane = makeTransport("Airplane");
getAirplane("Boeing");

inner function(Closure)은 outerfunction의 변수(위에서는 kind, count)를 다른 scope에서도 참조할 수 있고, parameter(위에서는 brand)를 이용해 호출되는 시점에 입력을 받을 수도 있다.
이렇게 closure를 활용해서 유사한 함수를 효율적으로 만들 수 있다.