⇨ 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다.(=내부함수에서 외부함수의 상태에 접근할수있는 권한을 준다.)
function outerFunc() {
let x = 10;
let innerFunc = function () { console.log(x); };
return innerFunc;
}
/**
* 함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
* 그리고 함수 outerFunc의 실행 컨텍스트는 소멸한다.
*/
let inner = outerFunc();
inner(); // 10
클로저에 의해 참조되는 외부함수의 변수 즉 outerFunc 함수의 변수 x를 자유변수(Free variable)라고 부른다. 클로저라는 이름은 자유변수에 함수가 닫혀있다(closed)라는 의미로 의역하면 자유변수에 엮여있는 함수라는 뜻이다.
클로저의 특징을 사용해 클래스 기반 언어의 private 키워드
를 흉내낼 수 있다.
function Counter() {
// 카운트를 유지하기 위한 자유 변수
let 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
//클래스버전
class Counter {
#count = 0;
increase() {
this.#count++;
console.log(this.#count);
}
decrease() {
this.#count--;
console.log(this.#count);
}
}
const counter = new Counter();
counter.increase(); //1
counter.increase(); //2
counter.decrease(); //1
생성자 함수 Counter의 변수 counter는 this에 바인딩된 프로퍼티가 아니라 변수이기때문에, 생성자 함수 Counter 내에서 선언된 변수 counter는 생성자 함수 Counter 외부에서 접근할 수 없다. 하지만 생성자 함수 Counter가 생성한 인스턴스의 메소드인 increase, decrease는 클로저이기 때문에 자신이 생성됐을 때의 렉시컬 환경인 생성자 함수 Counter의 변수 counter에 접근할 수 있다. 이러한 클로저의 특징을 사용해 클래스 기반 언어의 private 키워드를 흉내낼 수 있다.
let makeCounter = function() {
//private
let privateCounter = 0;
//private
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
};
let counter1 = makeCounter();
let counter2 = makeCounter();
alert(counter1.value()); /* 0 */
counter1.increment();
counter1.increment();
alert(counter1.value()); /* 2 */
counter1.decrement();
alert(counter1.value()); /* 1 */
alert(counter2.value()); /* 0 */
변수 privateCounter과 함수 changeBy는 외부에서 접근이 불가능하다.
increment, decrement, value만이 외부에서 접근이 가능하다.
참고 및 출처
클로저 - MDN
클로저 - poiemaweb