🌼 Closure
클로저(Closure)
는 내부함수가 외부함수의 맥락(Context)에 접근할 수 있는것으로 어떤 함수 A에서 선언한 변수 A를 참조하는 내부함수 b를 외부로 전달한 경우, A의 실행 컨텍스트가 종료된 이후에도 변수 a가 사라지지 않는 현상을 말한다.
- 내부함수는 외부함수의 지역변수에 접근할 수 있다.
- 외부함수의 실행이 끝나서 외부함수가 소멸된 이후에도 내부함수가 외부함수의 변수에 접근할 수 있다.
function outter() {
var title = 'coding everybody';
function inner() {
alert(title);
}
inner();
};
inner = outter();
inner();
- 매개변수(argument)는 함수 내부에서 지역변수로 사용된다.
- title이라는 argument에 접근을 get_title 혹은 set_title을 통해서만 할 수 있을 때 data의 encapsulation이 가능하며 private한 변수로서의 기능을 하게된다.
function factory_movie(title){
return {
get_title : function() {
return title;
},
set_title : function(_title) {
if (typeof _title === 'String') {
title = _title
} else {
alert('제목은 문자열이어야 합니다.');
}
}
}
}
ghost = factory_movie('Ghost in the shell');
matrix = factory_movie('Matrix');
🌻 클로저와 메모리 관리
메모리 누수
라는 표현은 개발자의 의도와 달리 어떤 것의 참조 카운트가 0이 되지 않아 Garbage Collector의 수거 대상이 되지 않는 경우이다. 만약 개발자의 의도와 상관없이 메모리 누수가 예상된다면 참조카운트를 0으로 만들어 GC의 수거 대상으로 만들어주면 된다.
let outer = (function() {
let a = 1;
let inner = function() {
return a++;
}
return inner;
})();
console.log(outer());
console.log(outer());
outer = null;
🌻 클로저 사용시 주의점
- 예상은 0,1,2,3,4가 출력될 것이라고 생각했으나 5가 5번 출력된다.
for문을 끝내기 위해서는 i = 5 인 경우가 실행이되는데 그 때의 i를 전역변수로 참고
하여 에상과 다른 값이 출력된 것이다.
let arr = []
for(let i = 0; i < 5; i++){
arr[i] = function(){
return i;
}
}
for(let index in arr) {
console.log(arr[index]());
}
› (5) 5
- 예상대로 0 ~ 4까지가 호출된다.
- arr[i]는
IIFE로 함수를 즉시 호출하는 방식을 사용
하였다. (IIFE는 global scope를 오염시키지 않기 위해 사용한다.)
- 내부 함수는
i라는 전역변수를 id로 받아 id를 return 하므로써 결국에는 내부 함수에 id라는 지역변수를 만들었다.
그리고 그 값들을 즉시 호출하는 방식을 통해 return 하였기 때문에 우리가 예상한대로 값이 출력
된 것을 알 수 있다.
let arr = [];
for(let i = 0; i < 5; i++) {
arr[i] = function(id) {
return function(){
return id;
}
}(i);
}
for(let index in arr) {
console.log(arr[index]());
}
› 0, 1, 2, 3, 4