JavaScript
Closure

클로저에 대해 설명해주세요

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

자신을 포함하고 있는 외부 함수보다 내부 함수가 더 오래 유지되는 경우가 있다. 이때 외부 함수 밖에서 내부 함수가 호출되더라도 외부 함수의 지역 변수에 접근할 수 있는 것을 클로저라고 한다.

function outer() {
  var x = 10; // 자유 변수로고도 부른다.
  function inner() {
    // 외부 함수의 지역 변수 x를 참조할 수 있다.
    console.log(x);
  }
  return inner;
}
 
var closure = outer();
closure(); // 10

다음 예시를 머릿 속에 그리면서 이야기를 진행하자.

여기서 클로저는 다음과 같은 특징을 지닌다.

  • 외부 함수의 지역 변수를 참조할 수 있다.
  • 외부 함수가 종료된 후에도 생존할 수 있다.
  • 외부 함수의 지역 변수에 의존한다.

클로저는 어디에 활용되는가

비공개 메서드

const counter = (function () {
  let privateCounter = 0;
 
  function changeBy(val) {
    privateCounter += val;
  }
 
  return {
    increment() {
      changeBy(1);
    },
 
    decrement() {
      changeBy(-1);
    },
 
    value() {
      return privateCounter;
    },
  };
})();
 
console.log(counter.value()); // 0
 
counter.increment();
counter.increment();
console.log(counter.value()); // 2
 
counter.decrement();
console.log(counter.value()); // 1

스코프

스코프는 함수를 호출할 때가 아니라 함수를 어디에 선언하였는지에 따라 정적으로 결정된다. 이를 렉시컬 스코프이라고 한다.

반대 의미인 다이나믹 스코프는 함수를 어디서 호출했는지에 따라 상위 스코프가 동적으로 결정된다.

즉 렉시컬 스코프에서 중요한 것은 스코프는 내가 정의한다는 것이다.

스코프 내 식별자는 유일해야 한다.

전역 스코프

어디서든지 참조 가능하다.

지역 스코프

자신의 지역 스코프와 하위 스코프만 참조 가능하다.

스코프 체인

스코프가 계층적으로 연결된 것을 의미한다.

가비지 컬렉터

가비지 컬렉터는 어떤 값을 참조하는 변수가 하나라도 있다면 없애지 않는다.

덕분에 내부 함수가 외부 함수의 어휘적 환경에 접근할 수 있게 된다.

function outer() {
  var x = 10;
  var y = "temp"; // 가비지 컬렉터의 수집 대상
  function inner() {
    console.log(x);
  }
  return inner;
}
 
var closure = outer();
closure(); // 10

여기서 y는 제거된다.

GPT로 문장 정리하기

클로저에 대해 설명해줘.

  • 함수와 함수가 선언된 어휘적 환경 사이의 관계
  • 함수가 다른 함수의 내부 함수일 때 발생하며 외부 함수의 변수에 접근할 수 있는 함수
  • 함수가 자신이 선언된 스코프 외부의 변수에 접근할 수 있는 것이 핵심
  • 주로 콜백 함수, 비동기 작업, private 변수 등을 다룰 때 유용하게 활용

키워드 정리

  • 어휘적 환경(렉시컬 환경)
  • 정적 스코프(렉시컬 스코프)
  • 스코프 체인
  • 가비지 컬렉터

참고 자료