Q 그렇다면 클로저란 무엇이고 어떤 특성을 갖고 있을까?
중첩함수가 외부함수의 렉시컬 환경을 참조하고 있을 때, 외부함수의 생명 주기가 끝나도 계속해 중첩함수를 통해 외부함수의 상태(state)를 변경할 수 있는 경우, 중첩함수를 가리켜 클로저(Closure)
라고 한다.
MDN에 따르면 클로저는 모든 함수가 생성될 때 만들어지지만, 정보 은닉의 목적으로 사용되는 클로저의 개념은 1. 중첩함수를 통해 외부함수의 스코프에 접근할 수 있으면서
2. 생명주기가 외부함수보다 긴 중첩함수
를 의미한다.
렉시컬 환경 : 식별자를 등록 관리하는 JS의 자료구조
- 렉시컬 환경의 참조가 단방향으로 연결돼 있고 이를 통해 중첩함수는 외부함수의 스코프(상위 스코프)를 참조할 수 있다.
const counter = (function () {
let num = 100;
return {
increase() {return ++num;},
decrease() {return --num;}
};
})(); // 즉시 실행 함수의 호출로 외부 함수의 생명 주기가 종료되고 클로저가 생성됨
// 중첩함수 increase|decrease를 통해 외부함수의 식별자 num의 상태 변경이 가능함
console.log(counter.increase()); // 101
console.log(counter.decrease()); // 100
console.log(counter.num); // undefined, 전역 코드에서 식별자 num을 참조할 수 없음
- 클로저의 외부함수 식별자 num을 가리켜 자유변수라고 한다.
- 클로저(Closure)는 자유변수에 대해 닫혀(Closed)있다.
클로저를 통해 사용자는 상태(state)를 안전하게 접근하고 변경할 수 있다.
2. 클로저의 구현
처럼 클로저 패턴은 OOP에서 상태 은닉과 객체 간 결합도(Coupling)를 낮추는데 사용된다. 함수형 프로그래밍(FP)
에서도 중요한 역할을 한다.함수형 프로그래밍
- 부수 효과가 없는 순수 함수들을 이용해 프로그램을 선언적으로 기술하는 프로그래밍 패러다임
- 조건문 | 반복문 | 부수 효과 등을 제거해 프로그램의 복잡성을 낮추고 코드의 유지 보수성을 높인다.
const sayHi = name => console.log(`Hi ${name}`);
const sayGoodBye = name => console.log(`Goodbye! ${name}`);
const say = conversation => name => conversation(name);
say(sayHi)('Park'); // Hi! Park
say(sayHi)('Lee'); // Hi! Lee
say(sayGoodBye)('Kim'); // Goodbye! Kim
say
라는 함수는 매개변수(conversation
)를 받아 클로저를 생성한다.name
)를 받아 최종적으로 말(say
)하는 동작을 수행한다. eg. Hi! Park
const items = [
{ name: 'Park', hobby: 'Hiking' },
{ name: 'Lee', hobby: 'Watching a movie' },
{ name: 'Kim', hobby: 'Basketball' }
];
// 1. 보조함수 where
const where = (key, value) => item => item[key] === value;
// 2. 보조함수 filter
const filter = where => items => items.filter(where);
// 3. 보조함수 applier
const applier = (key, value) => item => {
item[key] = value;
};
// 4.보조함수 map
const map = fnMap => targetItem => targetItem.map(fnMap);
// 5. 합성함수 getNewItems
const getNewItems = (items, applyFnc, whereFnc) => {
const newItems = items.map(item => ({ ...item }));
map(applyFnc)(filter(whereFnc)(newItems));
return newItems;
};
const newItems = getNewItems(
items,
applier('hobby', 'Soccer'),
where('name', 'Park')
);
console.log(items);
// [
// { name: 'Park', hobby: 'Hiking' },
// { name: 'Lee', hobby: 'Watching a movie' },
// { name: 'Kim', hobby: 'Basketball' }
// ]
console.log(newItems);
// [
// { name: 'Park', hobby: 'Soccer' },
// { name: 'Lee', hobby: 'Watching a movie' },
// { name: 'Kim', hobby: 'Basketball' }
// ]
함수형 프로그래밍(FP)에서 클로저와 화살표 함수는
1. 함수의 합성
2. 함수의 가독성
3. 부수 효과 제거
에 중요한 역할을 한다.