computer engineering

Javascript - 클로저(Closure)란? OOP와의 비교 및 고찰

제이훈 : 세상 모든 지식의 탐구자 2025. 5. 21. 13:28

클로저 (Closure)

  • 자신이 정의될 때의 스코프를 기억하는 함수
  • 외부 함수가 종료되어도 해당 스코프 변수에 접근 가능
function outer() {
  let count = 0;
  return function inner() {
    count++;
    console.log(count);
  };
}

const counter = outer();
counter(); // 1
counter(); // 2
  • inner는 outer의 count 변수에 접근 가능
  • 이 현상이 클로저

클로저 특징

  • 종료된 함수의 변수도 참조 중이면 GC 대상 아님
  • 은닉화 가능 (private 변수처럼 사용)
  • 상태 유지 가능 (카운터, 메모이제이션 등)

활용 예시

function createUser(name) {
  return {
    sayName: function () {
      console.log(name);
    }
  };
}

const user = createUser("Jay");
user.sayName(); // "Jay"
  • name은 외부에서 접근 불가하지만, sayName으로 참조 가능

var, let, const와 클로저

1) var와 클로저

function test() {
  var funcs = [];
  for (var i = 0; i < 3; i++) {
    funcs.push(function () {
      console.log(i);
    });
  }
  return funcs;
}

const result = test();
result[0](); // 3
result[1](); // 3
result[2](); // 3
  • 모두 3 출력
  • var는 함수 스코프 → i는 동일 참조

2) let과 클로저

function test() {
  var funcs = [];
  for (let i = 0; i < 3; i++) {
    funcs.push(function () {
      console.log(i);
    });
  }
  return funcs;
}

const result = test();
result[0](); // 0
result[1](); // 1
result[2](); // 2
  • let은 블록 스코프 → 매 반복마다 새로운 i 생성

3) const와 클로저

  • const도 블록 스코프
  • let과 유사하지만 재할당 불가

메모리 관리 측면에서의 클로저

function createCounter() {
  let count = 0;
  return function () {
    count++;
    console.log(count);
  };
}

const counter = createCounter();
counter(); // 1
counter(); // 2
  • count는 참조 중 → GC 대상 아님
  • 상태 유지 가능하지만, 메모리 누수 주의

요약

  • var: 함수 스코프 → 반복문 등에서 같은 참조 공유
  • let: 블록 스코프 → 반복마다 독립된 참조
  • const: let과 유사, 재할당 불가
  • 클로저는 강력하지만, 불필요한 참조 제거 필요

OOP와의 비교

  • 클로저는 클래스 기반 OOP의 은닉화·모듈화와 유사
  • 구조는 다르지만 개념적으로 유사
방식 클로저 (함수 기반) 클래스 (객체지향 기반)
데이터 은닉 함수 내부 변수 private 속성
공개 인터페이스 반환된 함수 public 메서드
상태 유지 함수 스코프 인스턴스 멤버
용도 간단한 모듈 복잡한 구조

클로저 예시

function Counter() {
  let count = 0;
  return {
    increment() {
      count++;
    },
    getCount() {
      return count;
    }
  };
}

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

C++ 클래스 예시

class Counter {
private:
    int count;

public:
    Counter() : count(0) {}

    void increment() {
        count++;
    }

    int getCount() const {
        return count;
    }
};

결론

  • 자바스크립트는 클래스 없이도 객체지향 설계 가능
  • 함수를 일급 객체로 다뤄 유사한 역할 수행

자바스크립트에도 클래스 문법이 있는데 왜 클로저를 쓰는지?

  • 함수형 스타일에 적합
  • 은닉 및 보안 처리에 유리
  • 가볍고 빠르게 객체 구성 가능
  • 귀찮아서