클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.
클로저는 자바스크립트 고유의 개념이 아니라 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어(Functional Programming language: 얼랭(Erlnag), 스칼라(Scala), 하스켈(Haskell), 리스프(Lisp)…)에서 사용되는 중요한 특성이다.
위 정의에서 말하는 “함수”란 반환된 내부함수를 의미하고 “그 함수가 선언될 때의 렉시컬 환경(Lexical environment)”란 내부 함수가 선언됐을 때의 스코프를 의미한다.
이를 조금 더 간단히 말하면, 클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다라고 말할 수 있다.
1. 전역변수를 줄일 수 있다.
전역변수는 예상치 못한 Side Effect를 일으킬 수 있기에 최대한 줄이는 것이 좋다. 하지만 프로그램 구현 시 함수 하나에 사용하는 전역변수가 필요한 순간이 있다. 이럴 때는 클로저가 유용하게 사용된다. 또한 클로저를 통해 데이터와 메소드를 묶어다닐 수 있기에 클로저는 모듈화에 유리하다.
다음 코드 같은 경우에 count를 전역변수로 사용해줘야 count가 증가를 해줄 수 있다. 이럴 경우에는 클로저를 사용하여 해결할 수 있다.
// Counter 예제
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick)
let count = 0
function handleCilck(){
count++
return count
}
다음 코드를 작성해 준다면 외부함수(handleClick)의 lexical environment를 참조하는 함수를 btn의 콜백함수로 이용해 전역객체 없이 구현할 수 있다.
// Counter Closure 예제
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick())
function handleCilck(){
let count = 0
return function (){
count++
return count
}
}
2. 비슷한 형태의 코드를 재사용률을 높일 수 있습니다.
// 새로운 태그를 만들 수 있는 함수 Closure 구현
const order = (food) => {
console.log(food + "을(를) 주문하셨습니다.");
return function (drink) {
return drink + "을(를) 추가로 주문하셨습니다."
}
}
const orderBurger = order("햄버거");
const orderPizza = order("피자");
console.log(orderBurger("콜라"));
console.log(orderPizza("사이다"));
3. 정보의 접근 제한(캡슐화) - Private Method 를 구성 할 수 있다.
💡 자바스크립트 내에서는 다른 언어와 달리 메소드를 Private Method 형태로 선언 할 수 있는 기능을 제공하지 않습니다. 그렇기에 이와 비슷한 형태로 정보의 접근을 제한하는 캡슐화를 클로저 개념을 이용하여 구성 할 수 있습니다.
💡 Private Method 란?