Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

pgg-dev

[JavaScript] 클로저 (closure) 본문

JavaScript

[JavaScript] 클로저 (closure)

pgg-dev 2020. 1. 6. 14:10

클로저란 내부 함수가 외부 함수의 지역변수에 접근할 수 있는 것이다.

 

 

1
2
3
4
5
6
7
8
function outter(){
    var title = 'coding everybody';  
    function inner(){        
        alert(title);
    }
    inner();
}
outter();

내부함수 inner에서 외부함수인 outter의 지역변수 title에 접근하여 경고창이 출력된다.

 

 

1
2
3
4
5
6
7
8
function outter(){
  var title = 'coding everybody';  
  return function(){        
    console.log(title);
  }
}
var inner = outter();
inner(); //coding everybody

외부함수의 호출이 끝나도 내부함수가 외부함수의 변수를 사용할 수 있다

7행 → 함수 outter를 호출하고, 그 결과로 이름 없는 함수가 변수 inner에 담긴다.

8행 → outter 함수는 실행이 끝났기 때문에 이 함수의 지역변수는 소멸되는 것이 자연스럽다.

하지만 함수 inner를 실행했을 때 지역변수의 값이 출력된다.

즉, 외부함수의 지역변수 title이 소멸되지 않았다는 것을 의미한다.

 

클로저란 내부함수가 외부함수의 지역변수에 접근 할 수 있고,

외부함수의 지역변수는 해당 변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미한다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function factory_movie(title){
  return {
      get_title : function (){
          return title;
      },
      set_title : function(_title){
          title = _title
      }
  }
}
var ghost = factory_movie('Ghost in the shell');
var matrix = factory_movie('Matrix');
 
console.log(ghost.get_title()); //Ghost in the shell 
console.log(matrix.get_title()); //Matrix
 
ghost.set_title('공각기동대');
 
console.log(ghost.get_title()); //공각기동대
console.log(matrix.get_title()); //Matrix

클로저는 객체의 메소드에서도 사용할 수 있다.

함수의 리턴 값으로 객체를 반환하고 있다.

객체의 메소드는 외부함수의 인자 값으로 전달된 지역변수 title을 사용하고 있다.

 

동일한 외부함수 안에서 만들어진 내부함수나 메소드는 외부함수의 지역변수를 공유한다.

17행 → set_title은 외부함수의 지역변수 title 값을 변경했다.

19행 → 출력 값으로 보아, set_title과 get_title 함수가 title의 값을 공유하고 있다는 의미다.

 

ghost와 matrix의 get_title의 결과가 다른 것은 

외부함수가 실행될 때마다 새로운 지역변수를 포함하는 클로저가 생성되기 때문이다.

ghost와 matrix는 서로 완전히 독립된 객체다.

 

factory_movie의 지역변수 title은 외부함수 내에 정의된 객체의 메소드에서만 접근할 수 있는 값이다.

즉, title의 값을 읽고 수정할 수 있는 것은 factory_movie 를 통해서 만들어진 객체뿐이라는 의미이다.

자바스크립트는 기본적으로 private한 속성을 지원하지 않는데,

클로저의 이러한 특성을 이용해서 private한 속성을 사용할 수 있게 된다.

 

 
1
2
3
4
5
6
7
8
9
var arr = []
for(var i = 0; i < 5; i++){
    arr[i] = function(){
        return i;
    }
}
for(var index in arr) {
    console.log(arr[index]()); //5 / 5 / 5 / 5 / 5 
}

배열 데이터에 값을 할당할 때 사용된 변수 i는 호출 시점에서 접근하기 때문에,

출력 시 반복문이 종료된 상태의 i의 값 5만을 참조한다.

 

 
1
2
3
4
5
6
7
8
9
10
11
var arr = []
for(var i = 0; i &lt; 5; i++){
    arr[i] = function(id) {
        return function(){
            return id;
        }
    }(i);
}
for(var index in arr) {
    console.log(arr[index]()); //0 / 1 / 2 / 3 / 4 
}
 

즉시 실행함수(IIFE)로 값을 할당하여, 호출과 참조 시점을 같게 해 준다.

 

 

 

[참고]

https://opentutorials.org/course/743/6544

https://heropy.blog/2017/11/10/closure/

Comments