190616 closure
3 min readSep 18, 2019
먼저 본인이 이해한 클로져란,
외부함수의 변수에 접근, 기억할 수 있는 내부함수.
일반적으로 return의 대상이 되는 함수로 쓰인다.
function getClosure() {
var text = 'variable 1';
return function() {
return text;
};
}
var closure = getClosure();
console.log(closure()); // 'variable 1'
내부함수에 존재하는 변수가 아닌 바깥의 text변수를 잘도 호출한다.
> 외부변수를 참조하는 내부함수는 따로 호출되어도 외부변수를 기억한다.
var base = 'Hello, ';
function sayHelloTo(name) {
var text = base + name;
return function() {
console.log(text);
};
}
var hello1 = sayHelloTo('승민');
var hello2 = sayHelloTo('현섭');
var hello3 = sayHelloTo('유근');
hello1(); // 'Hello, 승민'
hello2(); // 'Hello, 현섭'
hello3(); // 'Hello, 유근'
hello1, hello2, hello3은 생성당시 전달받은 argument를 통해 선언한 var text를 각자 다르게 보관하고 있다. 각자 다른 참조변수를 기억한다.
var i;
for (i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 100);
}
이 경우 10 만 10번 출력된다.
왜일까? 그 이유는 console.log(i)가 실행되기 전 대기시간 100ms가 채 되기전에 이미 바깥의 반복문이 전부 순회하면서 i가 10이 되어버린다.
결과적으로i는 최초 동작 예약 당시의 i를 기억하는 것이 아닌, 현재의 글로벌 변수 i를 출력하게 된다.
어떻게 해당 시점의 ‘ i ’를 기억하게 할까?
var i;
for (i = 0; i < 10; i++) {
(function(j) {
setTimeout(function() {
console.log(j);
}, 100);
})(i);
}
for문의 동작을 IIFE (즉시실행함수)형태로 만들어 클로져로 만들었다.
클로져는 만들어진 당시의 환경을 기억한다.
i는 (function(j){})(i)를 통해 IIFE내에 j로 주입이 되고, 각 IIFE의 환경으로 기억된다.