pgg-dev
[JavaScript] 클로저 (closure) 본문
클로저란 내부 함수가 외부 함수의 지역변수에 접근할 수 있는 것이다.
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 < 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)로 값을 할당하여, 호출과 참조 시점을 같게 해 준다.
[참고]
'JavaScript' 카테고리의 다른 글
[JavaScript] 호이스팅(Hoisting) (0) | 2020.01.09 |
---|---|
[ECMAScript6 / ES6] Promise (0) | 2020.01.08 |
[JavaScript] 프로토타입(prototype) (0) | 2020.01.07 |
[JavaScript] DOM 이란? (0) | 2019.12.03 |
[ECMAScript6 / ES6] 비구조화 할당 (구조 분해) / destructuring assignment (0) | 2019.11.20 |