클로저는 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어에서 사용되는 중요한 특성이다. 자바스크립트 고유의 개념이 아니므로 ECMAScript
명세에 클로저의 정의가 등장하지 않는다.
MDN
에서는 클로저는 ‘함수와 그 함수가 선언됐을 때의 렉시컬 환경과의 조합’이다. 라고 정의한다.
function outerFunc() {
var x = 10;
var innerFunc = function () { console.log(x); };
return innerFunc;
}
var inner = outerFunc();
inner(); // 10
함수 outerFunc는 내부 innerFunc를 반환하고 생을 마감한다. outerFunc의 실행 컨텍스트는 컨텍스트 스택에서 제거되었으므로 변수 x 또한 더 이상 유효하지 않아 접근할 수 있는 방법이 없어보인다.
하지만 outerFunc가 반환한 innerFunc를 실행하면 x의 값인 10을 출력한다. 즉, outerFunc의 x에 접근이 가능한 것이다.
자신을 포함하고 있는 외부 함수보다 내부 함수가 더 오래 유지되는 경우, 외부 함수 밖에서 내부 함수가 호출되었을 때 외부 함수의 지역 변수에 접근할 수 있는 함수를 클로저라고 부른다.
내부 함수가 유효한 상태에서 외부 함수가 종료되면 외부 함수의 실행 컨텍스트가 종료되어도 외부 함수의 실행 컨텍스트 내부의 활성 객체(변수의 정보를 담고 있는 객체 / AO) 는 내부 함수에 의해 참조되는 한 유효하다.
클로저는 주로 캡슐화와 정보 은닉에 사용된다. 아래 예제를 통해서 자세히 알아보자.
function createCounter() {
let count = 0;
function increment() {
count++;
console.log('Count:', count);
}
function getCount() {
return count;
}
return {
increment: increment,
getCount: getCount
};
}
// Usage
const counter = createCounter();
counter.increment(); // Count: 1
counter.increment(); // Count: 2
console.log(counter.getCount()); // Output: 2
카운터 기능은 createCounter
함수 내에 캡슐화되고 increment, getCount
메소드만 외부에 노출됩니다. 따라서 count
는 정보가 은닉되어 있으므로 직접 접근하지 못하고 제공된 메소드를 통해서만 count
를 조작할 수 있어 의도하지 않은 수정을 방지할 수 있습니다.