📚 클로저란 무엇인가요?

클로저란, ECMAScript에선 공식 사양으로 등장하진 않지만, 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.

❓ 클로저는 왜 사용 하나요?

클로저는 함수형 프로그래밍 방식에서 정보 은닉과 캡슐화를 통해 정보를 보다 안전하게 관리하기 위해 사용한다.

C++과 같은 객체지향 프로그래밍 언어와 달리 자바스크립트는 private 같은 접근 제한자를 제공하지 않는다.

때문에 자바스크립트에서 객체 프로퍼티를 안전하게 참조 및 변경하기 위해 클로저를 사용한다.

❓ 클로저는 언제, 어떻게 사용하나요?

클로저를 구현하는 방법은 아래 두가지 조건을 만족시켜 구현할 수 있다.

  1. 함수 안에 내부함수를 정의하고 내부함수는 외부함수의 식별자를 참조한다.
  2. 외부 함수의 반환값으로 내부함수를 반환하여 변수에 할당한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const counter = (function () {
// 카운트 상태 변수
let num = 0;

// 클로저인 메서드를 갖는 객체를 반환한다.
return {
increase() {
return ++num;
},
decrease() {
return num > 0 ? --num : 0;
},
};
})();

console.log(counter.increase()); // 1
console.log(counter.increase()); // 2

console.log(counter.decrease()); // 1
console.log(counter.decrease()); // 0

❗️ 주의점

클로저는 외부함수의 실행 컨텍스트가 제거되어도 내부함수가 외부함수의 변수를 기억하고 있는데 이는 추후에 메모리 누수가 발생할 수 있다.

예를 들어 리액트에서 useEffect 함수를 사용하여 렌더링 이후에 이벤트를 등록하였을 때, 이를 다시 렌더링이 되었을 때, 기존 이벤트를 클린업 해주지 않는 다면 같은 역할을 하는 이벤트가 중복등록이 되고 이는 성능상 문제를 일으킬 수 있으므로 이러한 점을 주의해야한다.

📌 정리

클로저는 보다 안전하게 객체를 다루기 위해 사용한다.

하지만 ES6에서 클래스가 도입되어 다른 객체지향 프로그래밍 언어처럼 private 접근 제한자가 생겨나 객체를 안전하게 관리할 수 있게 되었다.

예전에 페어프로그래밍을 하면서 DOM 요소를 참조하고 변경하는 클로저함수만 외부로 빼내어 해당 함수로만 DOM 요소를 조작할 수 있도록 코드를 구현해본 경험이 있습니다.