목차
클로저 (closure)
함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.
렉시컬 환경 (Lexical Environment)
식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조를 기록하는 자료구조로 실행 컨텍스트를 구성하는 컴포넌트이다.
function outerFunc() {
const x = 10;
const innerFunc = function () { console.log(x); };
return innerFunc;
}
/**
* 함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
* 그리고 함수 outerFunc의 실행 컨텍스트는 소멸한다.
*/
const inner = outerFunc();
inner(); // 10
- outerFunc 함수는 중첩 함수 innerFunc를 반환하고 생명 주기(life-cycle)를 마감한다.
➡️ outerFunc 함수의 실행이 종료되면 outerFunc 함수의 실행 컨텍스트는 실행 컨텍스트 스택에서 제거된다.
- 함수 outerFunc는 실행된 이후 실행 컨텍스트 스택에서 제거되었으므로 함수 outerFunc의 변수 x 또한 더이상 유효하지 않게 되어 변수 x에 접근할 수 있는 방법은 달리 없어 보인다.
- 그러나 위 코드의 실행 결과는 변수 x의 값인 10이다.
이처럼 자신을 포함하고 있는 외부함수보다 내부함수가 더 오래 유지되는 경우, 외부 함수 밖에서 내부함수가 호출되더라도 외부함수의 지역 변수에 접근할 수 있는데 이러한 함수를 클로저(Closure)라고 부른다.
클로저 (closure)의 활용
상태 유지
현재 상태를 기억하고 변경된 최신 상태를 유지
현재 상태(위 예제의 경우 .box 요소의 표시 상태를 나타내는 isShow 변수)를 기억하고 이 상태가 변경되어도 최신 상태를 유지해야 하는 상황에 매우 유용하다.
전역 변수의 사용 억제
// 함수를 인자로 전달받고 함수를 반환하는 고차 함수
// 이 함수가 반환하는 함수는 클로저로서 카운트 상태를 유지하기 위한 자유 변수 counter을 기억한다.
function makeCounter(predicate) {
// 카운트 상태를 유지하기 위한 자유 변수
var counter = 0;
// 클로저를 반환
return function () {
counter = predicate(counter);
return counter;
};
}
// 보조 함수
function increase(n) {
return ++n;
}
// 보조 함수
function decrease(n) {
return --n;
}
// 함수로 함수를 생성한다.
// makeCounter 함수는 보조 함수를 인자로 전달받아 함수를 반환한다
const increaser = makeCounter(increase);
console.log(increaser()); // 1
console.log(increaser()); // 2
// increaser 함수와는 별개의 독립된 렉시컬 환경을 갖기 때문에 카운터 상태가 연동하지 않는다.
const decreaser = makeCounter(decrease);
console.log(decreaser()); // -1
console.log(decreaser()); // -2
정보의 은닉
function Counter() {
// 카운트를 유지하기 위한 자유 변수
var counter = 0;
// 클로저
this.increase = function () {
return ++counter;
};
// 클로저
this.decrease = function () {
return --counter;
};
}
const counter = new Counter();
console.log(counter.increase()); // 1
console.log(counter.decrease()); // 0
- 생성자 함수 Counter의 변수 counter는 this에 바인딩된 프로퍼티가 아니라 변수다.
- counter가 this에 바인딩된 프로퍼티라면 ?
생성자 함수 Counter가 생성한 인스턴스를 통해 외부에서 접근이 가능한 public 프로퍼티가 되지만 생성자 함수 Counter 내에서 선언된 변수 counter는 생성자 함수 Counter 외부에서 접근할 수 없다.
- 생성자 함수 Counter가 생성한 인스턴스의 메소드인 increase, decrease는 클로저이기 때문에 자신이 생성됐을 때의 렉시컬 환경인 생성자 함수 Counter의 변수 counter에 접근할 수 있다.
Reference
https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures
클로저 - JavaScript | MDN
클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합입니다. 즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다. JavaScript에서 클로저는 함수 생
developer.mozilla.org
모던 자바스크립트 딥다이브 24장
https://poiemaweb.com/js-closure
Closure | PoiemaWeb
클로저(closure)는 자바스크립트에서 중요한 개념 중 하나로 자바스크립트에 관심을 가지고 있다면 한번쯤은 들어보았을 내용이다. execution context에 대한 사전 지식이 있으면 이해하기 어렵지 않
poiemaweb.com
'JavaScript' 카테고리의 다른 글
[JavaScript] 배열 고차 함수 (0) | 2023.03.17 |
---|---|
[JavaScript] 스코프 예제로 이해하기 (0) | 2023.03.17 |
[JavaScript] 식별자 네이밍 규칙 (0) | 2023.03.17 |
[JavaScript] 프로토타입 체인 (0) | 2023.03.16 |
[JavaScript] Prototype (0) | 2023.03.15 |
댓글