클로저
함수와 그 함수가 선언된 렉시컬 환경의 조합
함수가 선언될 때의 스코프를 기억하여, 함수가 생성된 이후에도 그 스코프에 접근할 수 있는 기능
클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다.
function init() {
var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
function displayName() {
// displayName() 은 내부 함수이며, 클로저다.
console.log(name); // 부모 함수에서 선언된 변수를 사용한다.
}
displayName();
}
init();
init()은 지역 변수 name과 함수 displayName()를 생성합니다.
displayName()은 init()안에 정의된 내부 함수이며 init() 함수 본문에서만 사용할 수 있습니다. 내부 함수에서 외부 함수의 변수에 접근 할 수 있기 때문에, displayName()은 부모 함수 init()에서 선언된 변수 name에 접근할 수 있습니다.
function makeAdder(x) {
return function (y) {
return x + y;
};
}
const add5 = makeAdder(5);
const add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
단일 인자 x를 받아서 새 함수를 반환하는 함수 makeAdder(x)를 정의합니다. 반환되는 함수는 단일인자 y를 받아서 x와 y의 합을 반환합니다.
본질적으로, makeAdder는 함수를 만들어내는 팩토리입니다. 이는 makeAdder함수가 특정한 값을 인자로 가질 수 있는 함수들을 리턴한다는 것을 의미합니다. 위의 예제에서, 함수 팩토리는 인자에 5와 10을 더하는 두 개의 새로운 함수들을 만들어 냅니다.
add5와 add10은 둘 다 클로저입니다. 이들은 같은 함수 본문 정의를 공유하지만 서로 다른 맥락(어휘)적 환경을 저장합니다. 함수 실행 시 add5의 어휘적 환경에서, 클로저 내부의 x는 5 이지만, add10의 맥락적 환경에서 x는 10입니다.
클로저는 어떤 데이터(렉시컬 환경)과 그 데이터를 조작하는 함수를 연관시켜주기 때문에 유용합니다.
클로저의 대표적인 사용 사례는
1. 데이터 은닉
클로저는 외부에서 접근할 수 없는 비공개 변수와 함수를 만들 수 있습니다. 이를 통해 데이터를 은닉하여 외부 접근을 막고, 데이터 무결성을 유지할 수 있습니다.
2. 모듈 패턴 구현
모듈 패턴은 특정 기능을 캡슐화하고, 외부에 공개하고자 하는 부분만 선택적으로 노출하여 코드의 응집력을 높이고, 유지보수성을 향상시키는 패턴입니다. 클로저를 활용하면 필요한 함수와 데이터만 외부로 노출함으로써 모듈 패턴을 쉽게 구현할 수 있습니다.