클로저(Closure)

클로저(Closure)는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 가르킨다.

내부함수

자바스크립트는 함수 안에서 또 다른 함수를 선언할 수 있다. 어떤 함수 안에서만 사용하는 함수가 있다면, 응집성을 위해 함수 내부에 함수를 만든다.

아래의 코드는 함수 outter 안에 지역변수 inner를 만들고, inner에 함수를 할당하는 것과 같다.

functino outter {
    function inner() {
        var title = 'coding everybody';
        alert(title);
    }
    inner();
}
outter();
var inner = {...}

아래의 코드는 내부함수가 외부함수의 지역변수에 접근할 수 있음을 보여준다. inner함수 내에 title 이라는 지역변수가 존재하지 않는다면 외부 함수인 outter에서 title이라는 변수를 찾는다.

functino outter {
    var title = 'coding everybody';
    function inner() {
        alert(title);
    }
    inner();
}
outter();

클로저란 외부함수가 종료된 이후에도 내부함수가 외부함수에 접근할 수 있다.

마지막에 inner()는 alert(title)이라는 구문을 실행한다는 의미이다. 이 때 title 은 외부함수에 존재하지만 말이다.

functino outter() {
    var title = 'coding everybody';
    return function() {
        alert(title);//coding everybody를 띄우는 것을 리턴한다.
    }
}
var inner = outter();//외부함수 실행한 결과를 변수 inner에 담는다.
inner();//inner변수가 담고있는 함수를 호출한다.

클로저의 실용적인 예

private variable은 아무나 소스코드를 수정하는 것을 방지한다. 아래의 코드에서 factory_movie가 외부함수이고, get_title과 set_title에 해당하는 메소드들이 내부함수라고 생각하면 된다. 즉, 외부함수의 지역변수에 접근할 수 있다.

function factory_movie(title) {
    return {//객체를 리턴한다. 2개의 속성과 메소드가 있다.
        get_title : function () {
            return title;
        },
        set_title : function(_title) {
            title = _title//이것은 결국 외부변수의 매개변수를 받는다.
        }
    }
}
ghost = factory_movie('Ghost in the shell');
matrix = factory_movie('Matrix');

alert(ghost.get_title());
alert(matrix.get_title());

ghost.set_title('공각기동대');//함수의 지역변수에 접근하여 값을 바꾼다.

alert(ghost.get_title());
alert(matrix.get_title());

위의 예제를 통해서 알 수 있는 것들은 다음과 같다.

  1. 클로저는 객체의 메소드에서도 사용할 수 있다. 위의 예제는 함수의 리턴값으로 객체를 반환하고 있다. 이 객체는 메소드 get_title과 set_title을 가지고 있다. 이 메소드들은 외부함수인 factory_movie의 인자값으로 전달된 지역변수 title을 사용하고 있다.

  2. 동일한 외부함수 안에서 만들어진 내부함수나 메소드는 외부함수의 지역변수를 공유한다. 17행에서 실행된 set_title은 외부함수 factory_movie의 지역변수 title의 값을 '공각기동대'로 변경했다. 19행에서 ghost.get_title();의 값이 '공각기동대'인 것은 set_title와 get_title 함수가 title의 값을 공유하고 있다는 것이다.

  3. 그런데 똑같은 외부함수 factory_movie를 공유하고 있는 ghost와 matrix의 get_title의 결과는 서로 각각 다르다. 그것은 외부함수가 실행될 때마다 새로운 지역변수를 포함하는 클로저가 생성되기 때문에 ghost와 matrix는 서로 완전히 독립된 객체가 된다.

  4. factory_movie의 지역변수 title은 2행에서 정의된 객체의 메소드에서만 접근 할 수 있는 값이다. 이 말은 title의 값을 읽고 수정 할 수 있는 것은 factory_movie 메소드를 통해서 만들어진 객체 뿐이라는 의미다. JavaScript는 기본적으로 Private한 속성을 지원하지 않는데, 클로저의 이러한 특성을 이용해서 Private한 속성을 사용할 수 있게된다.

Last updated