function outter(){ //외부함수
function inner(){ //내부함수
var title = 'coding everybody';
alert(title);
}
inner();
}
outter(); //coding everybody
//내부함수 inner에서 title을 호출했을때,
//외부함수 outter의 지역변수에 접근가능함을 보여줌
2. 클로저의 특성
클로저(closure)는 내부함수와 밀접한 관계를 가지고 있음
내부함수는 외부함수의 지역변수에 접근 할 수 있음
외부함수의 실행이 끝나서 외부함수가 소멸된 이후에도
내부함수가 외부함수의 변수에 접근 할 수 있음
이러한 메커니즘 → 클로저
function outter(){
var title = 'coding everybody';
return function(){
alert(title);
}
}
inner = outter();
inner(); //coding everybody
//이미 외부함수는 소멸되었지만, 외부함수의 지역변수 title이 소멸되지 않았음
3. 프라이빗 변수(private variable)
어떠한 정보를 아무나 수정하지 못하도록 방지하는 변수
(객체의 외부에서는 접근 할 수 없는 외부에 감춰진 속성이나 메소드를 의미)
Private 속성을 통해 객체의 내부에서만 사용해야 하는 값이
노출됨으로서 생길 수 있는 오류를 줄일 수 있음
클로저는 객체의 메소드에서도 사용 가능
동일한 외부함수 안에서 만들어진 내부함수나 메소드(get_title / set_title)는
외부함수의 지역변수(title)를 공유
JavaScript는 기본적으로 Private한 속성을 지원하지 않는데,
클로저의 이러한 특성으로 Private한 속성을 사용할 수 있음
function factory_movie(title){ //매개변수는 함수 속에서 지역변수로 사용
return {
get_title : function (){ //내부함수
return title;
},
set_title : function(_title){
title = _title //클로저는 객체로도 사용 가능
}
}
}
ghost = factory_movie('Ghost in the shell');
matrix = factory_movie('Matrix');
//접근하는 title값이 서로 다름
alert(ghost.get_title()); //Ghost in the shell
alert(matrix.get_title()); //Matrix
//factory_movie의 지역변수를 가져오게 됨
ghost.set_title('공각기동대');
alert(ghost.get_title()); //공각기동대
alert(matrix.get_title()); //matrix
// factory_movie는 오직 get_title과 set_title라는
// 메소드를 통해서만 접근이 가능한 함수
4. 클로저의 응용
var arr = []
for(var i = 0; i < 5; i++){
//i의 값은 이 함수의 외부함수가 아님
arr[i] = function(){
return i;
}
}
for(var index in arr) {
console.log(arr[index]());
} //55555
/* 이 함수를 내부함수로 하는 외부함수를 정의하고
그 외부함수의 지역변수 값을 내부함수가 참조하도록 하면 01234를 얻을 수 있음 */
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]());
} //01234