closure에 대해 알아보자!
MDN의 정의
말이 조금 어렵다...! 풀어서 이해해보자!
렉시컬 스코프란?
- JS엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정한다. 이를 렉시컬 스코프(정적스코프)라 한다.
- 정확히 말하면 렉시컬 환경의 "외부 렉시컬환경(outer lexical scope)에 대한 참조"에 저장할 참조값, 즉 상위 스코프에 대한 참조는 함수가 정의되어 평가될 시점의 환경에 의해 결정된다. 이것이 렉시컬 스코프이다!
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를 외부 렉시컬 환경 참조에 저장하고 있기 때문에 접근 할 수 있다.
Author And Source
이 문제에 관하여(closure에 대해 알아보자!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jinn2u/closure에-대해-알아보자저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)