클로저(Closure)란?

주형(Jureamer)·2022년 3월 14일
3

클로저란?

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.

클로저는 자바스크립트 고유의 개념이 아니라 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어(얼랭(Erlnag), 스칼라(Scala), 하스켈(Haskell), 리스프(Lisp)…)에서 사용되는 중요한 특성이다.

위 정의에서 말하는 “함수”란 반환된 내부함수를 의미하고 “그 함수가 선언될 때의 렉시컬 환경(Lexical environment)”란
내부 함수가 선언됐을 때의 스코프를 의미한다.

즉, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수를 말한다.

이를 조금 더 간단히 말하면,
클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다라고 말할 수 있겠다.

클로저에 의해 참조되는 외부함수의 변수 즉 outerFunc 함수의 변수 x를 자유변수(Free variable)라고 부른다. 클로저라는 이름은 자유변수에 함수가 닫혀있다(closed)라는 의미로 의역하면 자유변수에 엮여있는 함수라는 뜻이다.

실행 컨텍스트의 관점에 설명하면, 내부함수가 유효한 상태에서 외부함수가 종료하여 외부함수의 실행 컨텍스트가 반환되어도, 외부함수 실행 컨텍스트 내의 활성 객체(Activation object)(변수, 함수 선언 등의 정보를 가지고 있다)는 내부함수에 의해 참조되는 한 유효하여 내부함수가 스코프 체인을 통해 참조할 수 있는 것을 의미한다.

클로저가 필요한 이유

1. 전역변수를 줄일 수 있다.

전역변수는 예상치 못한 Side Effect를 일으킬 수 있기에 최대한 줄이는 것이 좋다.문에 최대한 전역변수를 줄여서 코딩해야한다.

하지만 프로그램 구현 시 함수 하나에 사용하는 전역변수가 필요한 순간이 있다. 이럴 때 클로저가 유용하게 사용된다.

// Counter 예제
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick)

let count = 0
function handleCilck(){
  count++
  return count
}

//위와 같은 경우에 count를 전역변수로 사용해줘야 count가 증가를 해줄 수 있음
//이럴경우 클로져를 사용해서 해결할 수 있다.


// Counter Closure 예제
const btn = document.querySelector('button')
btn.addEventListener('click',handleClick())

function handleCilck(){
  let count = 0
  return function (){
    count++
    return count
  }
}
// 위와 같이 작성해 준다면 외부함수(handleClick)의 lexical environment를 참조하는 함수를 
// btn의 콜백함수로 이용해 전역객체 없이 구현할 수 있다.

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("사이다"));

//<b><i>This is my content!</i></b>

인자에 open,close,content를 한번에 다 받는다면,This is my content! 와 같은 값을 출력을 하고 싶을 때 가독성이 떨어질 수 있다.

하지만 클로져로 구현하면 코드의 가독성도 좋은 재사용하기 편한 코드를 구현할 수 있음.

마치며..
클로저를 사용함으로써 얻는 이점들이 많은데 실제로 이용해서 코드를 짜본 적이 별로 없기 때문에 완벽히 이해하기는 아직은 무리인 것 같다.
많은 예제를 접하고 사용 해보면서 훈련을 해보려고 한다!

Reference

profile
작게라도 꾸준히 성장하는게 목표입니다.

2개의 댓글

comment-user-thumbnail
2023년 8월 22일

면접에서 클로저를 물어보는데 정확히 이해를 못한상태에서 답변하려니 어려웠는데, 이렇게 알기 쉽게 예제를 올려주셔서 너무 감사합니다!

답글 달기
comment-user-thumbnail
2023년 11월 13일

"함수형 프로그래밍 언어(얼랭(Erlnag), 스칼라(Scala), 하스켈(Haskell), 리스프(Lisp)…)에서 사용되는 중요한 특성이다." 부분에서 > "Erlang" 오타 있어요

답글 달기