Published On

클로저와 렉시컬 스코프


클로저(Closure)란?

클로저(Closure)라는 용어는 함수가 자신이 선언될 때의 스코프(Lexical Scope)"닫아둔다"는 의미에서 유래했습니다.

즉, 함수가 선언된 환경에 있는 변수와 값들을 계속해서 기억하고 유지하는 구조를 의미합니다.

이는 자바스크립트의 함수형 프로그래밍에서 특히 중요한 개념입니다.

클로저는 주로 함수 내부에 정의된 변수를 외부에서 은닉하면서도 상태를 관리할 수 있게 도와줍니다.

React의 useState 훅과 비슷한 구조를 제공하며, 외부에서는 클로저 내부 변수에 직접 접근할 수 없도록 은닉하는 데 유용합니다.


렉시컬 스코프(Lexical Scope)란?

렉시컬 스코프(Lexical Scope)는 함수의 스코프가 정의되는 시점에 따라 결정되는 변수의 유효 범위를 의미합니다.

이는 자바스크립트에서 코드를 작성한 위치에 따라 어떤 변수에 접근할 수 있는지가 결정된다는 것을 뜻합니다.

  • 렉시컬 스코프에서는 함수가 선언될 당시의 스코프를 기억합니다.
  • 따라서 클로저는 이러한 렉시컬 스코프를 활용해 외부 함수의 변수를 내부 함수에서 유지할 수 있습니다.

기본 클로저 예제

function outer(count) {
  return function inner() {
    return count++; // 외부 함수의 변수 count에 접근 (렉시컬 스코프)
  };
}

const counter = outer(10);
console.log(counter()); // 10
console.log(counter()); // 11
console.log(counter()); // 12

위 예제에서 inner 함수는 outer 함수가 종료된 후에도 count 변수에 접근할 수 있습니다.

이는 렉시컬 스코프가 유지되고, 함수가 그 환경을 기억하기 때문입니다.

이렇게 함수가 외부 함수의 상태를 계속해서 기억할 수 있는 구조가 바로 클로저입니다.


클래스와 클로저 비교

클래스로 상태관리

이제 클래스와 클로저를 비교하는 예제를 보여드리겠습니다.

클래스로 상태 관리를 할 수 있지만 자바스크립트에서는 클로저로 구현하는 것이 더 일반적입니다.

class Counter {
  #count; // private 필드

  constructor(initialValue = 0) {
    this.#count = initialValue;
  }

  increment() {
    return ++this.#count;
  }

  decrement() {
    return --this.#count;
  }

  getCount() {
    return this.#count;
  }
}

const counter = new Counter(0);
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount()); // 2

클로저로 상태관리

React의 훅과 비슷하게, 클로저를 사용하여 간단한 상태 관리 훅을 구현할 수 있습니다.

function useCounter(initialValue = 0) {
  let count = initialValue;

  return {
    increment: () => ++count,
    decrement: () => --count,
    getCount: () => count,
  };
}

const counter = useCounter(0);
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getCount()); // 2

요약

항목클로저를 활용한 상태 관리클래스를 활용한 상태 관리
설계 방식함수와 스코프를 활용하여 상태를 유지클래스 인스턴스를 통해 상태를 관리
비공개 상태 유지클로저 내부 변수에 외부에서 접근 불가# 키워드로 private 필드를 선언해 캡슐화 제공
메모리 관리클로저는 사용되지 않으면 가비지 컬렉터가 회수인스턴스가 많아지면 메모리 사용량 증가 가능
재사용성여러 함수 조합으로 유연하게 재사용 가능클래스를 상속하거나 인스턴스를 통해 재사용 가능
복잡성간단한 상태 관리에 적합복잡한 상태와 여러 메서드 관리에 적합
성능클로저가 많아질수록 메모리 사용이 증가할 수 있음인스턴스가 많아질수록 메모리 사용량 증가