본문 바로가기

JavaScript

클로저

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

클로저란 내부함수가 외부함수의 지역변수에 접근 할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미한다.

function outter(){
    var title = 'coding everybody';  
    return function(){        
        alert(title);
    }
}
inner = outter();
inner();

코드 설명

함수 outter를 호출하고 있다. 그 결과가 변수 inner에 담긴다. 그 결과는 이름이 없는 함수다.

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

하지만 함수 inner를 실행했을 때 coding everybody가 출력된 것은 외부함수의 지역변수 title이 소멸되지 않았다는 것을 의미한다.

 

 

 

응용

var arr = []
for(var i = 0; i < 5; i++){
    arr[i] = function(){
        return i;
    }
}
for(var index in arr) {
    console.log(arr[index]());
}
배열들은 함수들의 참조만 가지고 있을 뿐입니다.(실행되지 않는다!) 

arr[0] = function(){
return i;
}
arr[1] = function(){
return i;
}
arr[2] = function(){
return i;
}
arr[3] = function(){
return i;
}
arr[4] = function(){
return i;
}

i++

//

console.log(arr[0]()); // i = 5
console.log(arr[1]()); // i = 5
console.log(arr[2]()); // i = 5
console.log(arr[3]()); // i = 5
console.log(arr[4]()); // i = 5

코드 설명 

- 위 코드에서 루프가 다 돌고 난후 `i++`이 실행되어 최종적으로 i값은 5이다
- 첫번재 반복문에서 arr[index]에 담긴 것은 특정한 값이 아니라 함수이다.
- console.log(arr[index]());를 호출했을 때, 외부의 컨텍스트에 접근할 수 있을 것으로 기대하였다.
- 하지만 for문의 i는 외부함수의 변수가 아니었다. 훼이크!
- 따라서 단순히 arr[index]에 담긴 함수가 5회 실행되어 현재의 i값인 5를 출력하였다.

 

따라서 위 코드는 아래와 같이 수정해야 한다.

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]());
}

 

 

Reference

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

'JavaScript' 카테고리의 다른 글

구조분해할당  (0) 2019.08.19
setTimeout(), Promise, async/await 비교  (0) 2019.07.29
JSON  (0) 2019.07.23
async await  (0) 2019.07.23
call(), apply(), bind()  (0) 2019.07.23