[JS] 클로저(closures), 클로저 함수란?

jellyjw·2022년 11월 8일
0
post-thumbnail

클로저(closures)

함수와 함수가 선언된 어휘적(lexical)환경의 조합을 말한다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다.
출처: MDN

자바스크립트는 함수가 호출되는 환경과는 별개로 기존에 선언되어 있던 어휘적 환경을 기준으로 변수를 조회하려고 하는데,
외부 함수의 변수에 접근할 수 있는 내부 함수클로저 함수라고 한다.

클로저 함수

클로저는 외부 함수의 컨텍스트에 접근할 수 있는 내부 함수를 뜻합니다. 외부 함수의 실행이 종료된 후에도, 클로저 함수는 외부 함수의 스코프, 즉, 함수가 선언된 어휘적 환경에 접근할 수 있습니다.

const add = function(x) {
  return function(y) {
    return x + y;
  }
}

위 함수의 리턴값은 함수의 형태이다. 즉, 함수를 리턴하는 함수인 것이다
클로저는 리턴하는 함수에 의해 스코프가 구분되는데 클로저의 핵심은 스코프를 이용해서 변수의 접근 범위를 닫는(closure)데에 있다.
따라서, 함수를 리턴하는 만큼이나 변수가 선언된 곳이 중요하다.

const add = function(x) {
  return function(y) {
    return x + y;
  }
}

다시한번 동일한 예제에서 처음 등장하는 매개변수 x 는 가장 바깥쪽에 있으니 외부함수,
매개변수가 y 인 함수는 안쪽에 있으니 내부 함수라고 불렀을 때
1. 외부 함수는 y에 접근이 가능한가?
2. 내부 함수는 x에 접근이 가능한가?

1번의 답은 no이다. 바깥 스코프에서는 안쪽 스코프로의 접근이 불가하다.
2번의 답은 yes이다. 안쪽 스코프는 바깥 스코프에서 선언된 변수에 접근이 가능하다.


클로저 함수의 특징

  • 내부함수는 외부함수에 선언된 변수에 접근이 가능하다는 특징이 있다.
  • 일반 함수는 함수 실행이 끝나고 나면 내부 변수를 사용할 수 없지만, 클로저 함수는 외부 함수의 실행이 끝나더라도 외부 함수 내 변수가 메모리상에 저장된다.(어휘적 환경을 메모리에 저장하기 때문에 가능한 일)
  • 특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용할 수 있게 한다.

클로저 모듈 패턴

const makeCounter = () => {
  let value = 0;
  
  return {
  	increase: () => {
      value = value + 1
  	},
    decrease: () => {
      value = value - 1
    },
    getValue: () => value
  }
}

const counter1 = makeCounter();
    

클로저 모듈 패턴이라고 불리는 아주 유용한 패턴이다.

위 예제를 보면, makeCounter 라는 함수는 내부 함수를 단 하나 리턴하는 것에 그치지 않고 여러개의 내부 함수를 리턴하도록 객체에 담았다. 따라서 counter1 은 객체이다.

외부 스코프는 내부 스코프에 접근할 수 없다라는 규칙에 의해 value 값을 직접 수정하는것은 불가능하지만, 리턴하는 객체가 제공하는 메서드를 통해 value 값을 간접적으로 조작할 수 있는데 이것이 바로 정보의 접근 제한(캡슐화)이다.

만약 스코프로 value값을 감싸지 않았더라면 value는 전역변수가 됐을 것이다. 하지만 위에서도 언급했듯 전역변수를 많이 만드는 건 그다지 좋은 일이 아니다.

이처럼, 함수 재사용성을 극대화하여 함수 하나를 완전히 독립적인 부품 형태로 분리하는 것을 모듈화라고 한다. 즉, 클로저는 데이터와 메서드를 묶어서 다룰 수 있기 때문에 모듈화에 유리하다.

클로저의 단점

  • 일반 함수였다면 함수 실행 종료 후 가비지 컬렉션(참고 자료: MDN '자바스크립트의 메모리 관리') 대상이 되었을 객체가, 클로저 패턴에서는 메모리 상에 남아 있게 된다. 외부 함수 스코프가 내부 함수에 의해 언제든지 참조될 수 있기 때문이다.
  • 클로저를 남발할 경우 퍼포먼스 저하가 발생할 수도 있다.
profile
남는건 기록뿐👩🏻‍💻

0개의 댓글