본문 바로가기

Front/Java Script

클로저(closure)

 

클로저(closure)

내부함수가 외부함수의 맥락에 접근할 수 있는 것

function outter(){
   var title = 'Hello world';
   
   return function (){
              alert(title);
         }
}

var inner = outter();
inner();

외부함수가 종료된 이후에도 내부함수에서 외부함수의 지역변수에 접근할 수 있다.

 

 

위의 코드에서 outter()가 한번 실행되고, 그 결과로 반환된 함수가 inner에 할당 되었다.

outter는 이미 종료되었지만, inner 함수를 호출할 때 마다 outter의 지역변수인 title에 접근이 된다.

 

 


 

private variable

정보를 아무나 수정하는 것을 방지하기 위해 사용된다.

function factory_movie (title){       //외부함수

    return {
          get_title : function(){         //내부함수
                    console.log(title);
          },
          set_title : function(_title){
                    title = _title;     /*title의 타입을 거를 수 있는 로직 사용가능*/
          }
}

var ghost = factory_movie('Ghost in the shell');
var matrix = factory_movie('Matrix');

ghost.get_title();     // Ghost in the shell
matrix.get_title();    // Matrix

ghost.set_title('공각기동대');
ghost.get_title();     // 공각기동대
matrix.get_title();   // Matrix

 

ghost와 matrix는 같은 함수를 통해서 만들어진 객체이지만 각각 다른 title을 가지고 있다.

factory_movie 함수가 실행될 때를 기준으로, 다시 말하면 ghost변수에 객체가 할당될 때를 기준으로.

title이라는 데이터를 가지고 있다.

그러므로 set_title로 ghost의 title을 변경하더라도 matrix에는 영향을 미치지 않는다.

또한, set_title을 통해서만 변수를 수정할 수 있으므로 

클로저는 프라이빗한 변수를 사용하는 좋은 메커니즘이다.

 


클로저의 응용

 

1. 잘못된 예

  var는 전역변수이므로, 그 당시의 i를 담지 못한다.

  마지막 i의 값만 반환되므로 전부 5로 출력

var arr = []

for(var i = 0; i < 5; i++){
     arr[i] = function(id){
           return i;
     };
}

for(var index in arr){
      console.log(arr[index]());
}

 

2. 올바른 예

  외부함수가 실행되면서 인자로 받은 i값은 외부함수의 지역변수가 되므로,

  내부함수의 id는 외부함수가 실행된 시점의 값을 참조한다.

  결과적으로 0, 1, 2, 3, 4 가 출력된다.

var arr = []

for(var i = 0; i < 5; i++){
     arr[i] = function(id){  //외부함수
           return function(){  //내부함수
                    return id;
           }
     }(i);
}

for(var index in arr){
      console.log(arr[index]());
}

 

 

 

출처

클로저

opentutorials.org/course/743/6544