클로저
클로저는 내부함수가 외부함수의 지역변수에 접근할 때 내부함수가 소멸되기 전까지 내부함수가 접근한 지역변수가 소멸되지 않는 현상을 말한다.
원래 외부함수 내에 정의된 지역변수는 외부함수가 호출되고나서 소멸되면 함께 소멸되어야 하지만, 내부함수가 그 지역변수에 접근하고 있다면,
그 내부함수가 소멸되기 전까지 지역변수는 소멸되지 않는데 이러한 메커니즘을 클로저라고 한다.
클로저의 정의는 다양하다.
1. 외부함수의 지역변수를 남겨두는 현상.
2. 외부함수 내의 변수가 살아있는 것이기 때문에, 외부함수로 인해 생겨난 공간.
3. 리턴된 내부함수 자체.
4. 살아남은 외부함수 내의 지역변수 자체.
위의 정의들 모두 클로저와 관련된 개념이라고 볼 수 있다.
<script>
function closer(name) {
var output = 'My name is ' + name;
return function() {
alert(output);
}
};
var test1 = closer('Lee');
test1();
</script>
함수 closer의 지역변수 output은 함수가 호출되고 나면 소멸되어 외부에서 접근할 수가 없다.
그래서 주석처리된 문장을 실행할 경우에는 오류가 발생한다.
하지만 리턴하는 내부함수인 익명함수가 변수 output을 사용하고 있다.
따라서, 리턴된 익명함수를 변수 test1에다가 저장하고 test1을 이용해서 저장된 함수를 호출하면 변수 output이 소멸되지 않고 있음을 알 수 있다.
이것이 바로 클로저이다.
아래의 코드를 살펴보면 클로저의 특징을 좀 더 알 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <script> function music_artist(artist) { return { get_music : function() { return artist; }, set_music : function(_artist) { artist = _artist; } } } var rock = music_artist('Beatles'); var dance = music_artist('Lady Gaga'); alert(rock.get_music()); //Beatles 출력 alert(dance.get_music()); //Laydy Gaga 출력 rock.set_music('Oasis'); alert(rock.get_music()); //Oasis 출력 alert(dance.get_music()); //Laydy Gaga 출력 </script> | cs |
1. 함수 music_artist가 함수가 아닌 메소드를 가진 객체를 반환하고 잇다. 클로저는 객체를 반환 할 때도 사용할 수 있다.
지역변수인 artisit를 객체 내부에 있는 두개의 메소드에서 사용함으로써 클로저를 사용하고 있다.
2. 13행과 14행에서 두개의 변수가 동일한 함수 music_artist의 리턴값을 저장하고 있지만 16행과 17행에서 각각의 결과는 다르다.
즉, 외부함수가 실행 될 때마다 새로운 지역변수를 가진 클로저가 생성된다는 것을 알 수 있다.
3. 19행에서 set_music메소드를 호출하여 지역변수의 값을 바꾼뒤, 21행에서 get_music메소드를 호출 하였더니
set_music메소드로 변경한 지역변수 값이 출력되었다.
이를 통해서 하나의 외부함수 내에 정의된 내부함수나 메소드는 외부함수의 지역변수를 공유한다는 것을 알 수 있다.
4. 외부함수 music_artist의 지역변수 artist는 내부에 정의된 메소드를 통해서만 값을 변경하거나 사용할 수 있다.
이는 클로저를 통해서 자바스크립트에서 Private한 속성을 사용할 수 있게 해준다.