
inner()은 자신을 포함하는 함수 outer() 안의 변수 name에 접근 가능하다.function outer() {
var name = "closer"; // name은 outer에 의해 생성된 지역 변수
function inner() {
// inner() 은 내부 함수이며, 클로저다.
console.log(name); // 부모 함수에서 선언된 변수를 사용한다.
}
inner();
}
outer();
add3 함수가 생성된 이후에도 상우 함수인 adder의 x에 접근이 가능하다.function adder(x){
return function(y){
return x + y;
}
}
const add3 = adder(3); //function(y){ return 3 + y; }
console.log(add3(2)); //5
console.log를 실행했을 때, 콘솔은 l1을 출력할 수 없다.fn2()가 fn1() 내부에서 실행했다 하더라도, 처음 정의한 곳은 fn1() 외부이기 때문이다.let l0 = 'l0';
function fn2(){
let l2 = 'l2';
console.log(l0, l1, l2);
}
function fn1(){
let l1 = 'l1';
fn2();
}
fn1();
클로저를 사용하는 경우
- class처럼 사용하고 싶을 때
- 정보의 은닉화
클로저의 경우 잘못 사용할 경우 데이터가 GC에 수거되지 못해 메모리 누수 현상이 일어날 수 있지만, 클로저를 사용하게 되면 가질 수 잇는 장점들이 있기 때문에 메모리 누수문제를 해결할 수 있다면 클로저를 사용하는 것이 좋다.
(function a(){
let s='s';
})() //a is not defined
function counter() {
let count = 0;
return {
increment: function () {
count++;
return count;
},
reset: function () {
count = 0;
return count;
}
};
}
const myCounter = counter();
console.log(myCounter.increment()); // 1
console.log(myCounter.increment()); // 2
console.log(myCounter.reset()); // 0
console.log(myCounter.increment()); // 1
counter 함수는 클로저를 반환한다. 반환된 객체에는 increment와 reset이라는 두 개의 메서드가 있다. increment 메서드는 카운터를 1씩 증가시키고 현재 카운트를 반환하며, reset 메서드는 카운터를 0으로 리셋하고 현재 카운트를 반환한다.myCounter 객체를 통해 메서드들을 호출할 수 있고, 클로저를 사용하여 카운터 변수를 외부에서 직접 접근하지 못하도록 은닉화되어 있다.