말이 조금 어렵다...! 풀어서 이해해보자!
function init() {
var name = "Mozilla";
function displayName() { // displayName() 은 내부 함수이며, 클로저다.
console.log(name) //Mozilla
}
displayName();
}
init();
위의 코드에서 보면 displayName 함수는 name이라는 지역변수를 가지고 있지 않다. 하지만 init을 실행한다면 mozilla는 잘 출력된다. 이는 displayName이 정의되는 시점에서 외부 렉시컬 환경 참조에 상위 스코프를 저장하였기 때문이다
따라서 자신만의 지역 변수를 가지고 있지 않기 때문에 this.name대신 상위 스코프의 name을 불러온다.
function makeAdder(x) {
var y = 1;
return function(z) {
y = 100;
return x + y + z;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 107 (x:5 + y:100 + z:2)
console.log(add10(2)); // 112 (x:10 + y:100 + z:2)
add5와 add10은 같은 makeAdder를 사용하지만 다른 맥락적 환경을 사용하기 때문에 다른 결과가 나온다!
var counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
};
})();
console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1
counter는 즉시실행함수이기 때문에 counter의 privateCounter에 접근할 방법이 없다. 하지만 내부함수changeBy는 상위 스코프의 변수인 privateCounter를 외부 렉시컬 환경 참조에 저장하고 있기 때문에 접근 할 수 있다.