[JS] 클로저(Closure) 생성자함수 (new Function) 비교

javaScript 기초를 탄탄하게 다져보자

Posted by lim.Chuck on February 4, 2025

[JavaScript]

기초

  1. [JS] Js기초
  2. [JS] Js기초 변수
  3. [JS] Js기초 자료형
  4. [JS] Js기초 형변환
  5. [JS] Js기초 연산자
  6. [JS] Js기초 반복문
  7. [JS] Js기초 switch
  8. [JS] Js기초 function
  9. [JS] Js기초 객체
  10. [JS] Js기초 배열

중급

  1. [JS] Js중급 호이스팅(Hoisting)과 TDZ(Temporal Dead Zone)
  2. [JS] Js중급 생성자함수
  3. [JS] 객체 메소드(Object methods), 계산된 프로퍼티(Computed property)
  4. [JS] 심볼(Symbol)
  5. [JS] WeakMap WeakSet
  6. [JS] 숫자, 수학 method (Number, Math)
  7. [JS] 문자열 메소드(String methods)
  8. [JS] 배열 메소드(Array methods)
  9. [JS] 구조 분해 할당 (Destructuring assignment)
  10. [JS] 매개변수 리스트와 전개 문법(Rest parameters and spread syntax)
  11. [JS] 클로저(Closure)
  12. [JS] setTimeout / setInterval
  13. [JS] call / apply / bind
  14. [JS] 상속, 프로토타입(Prototype)
  15. [JS] 클래스(Class)
  16. [JS] 클로미스(Promise)
  17. [JS] 비동기 처리(Async/Await)
  18. [JS] Generator
  19. [JS] 메모리 릭(Memory Leak)

1. 일반 함수로 클로저 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function createCounter() {
  let count = 0; // private 변수처럼 동작

  return {
    increase: function () {
      return ++count;
    },
    decrease: function () {
      return --count;
    },
    getCount: function () {
      return count;
    },
  };
}

const counter1 = createCounter();
const counter2 = createCounter();

console.log(counter1.getCount()); // 0
counter1.increase(); // 1
console.log(counter2.getCount()); // 0 (독립적인 스코프)

2. new 생성자 함수로 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Counter() {
  let count = 0; // private 변수처럼 동작

  this.increase = function () {
    return ++count;
  };

  this.decrease = function () {
    return --count;
  };

  this.getCount = function () {
    return count;
  };
}

const counter1 = new Counter();
const counter2 = new Counter();

console.log(counter1.getCount()); // 0
counter1.increase(); // 1
console.log(counter2.getCount()); // 0 (독립적인 스코프)

주요 차이점

  1. this 바인딩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 일반 함수
function createCounter() {
  let count = 0;
  return {
    increase() {
      return ++count;
    },
  };
}

// new 생성자 함수
function Counter() {
  let count = 0;
  this.increase = function () {
    return ++count;
  };
}

// this 바인딩 차이 확인
const counter1 = createCounter();
const counter2 = new Counter();

console.log(counter1.constructor); // Object
console.log(counter2.constructor); // Counter
  1. 프로토타입 체인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Counter() {
  let count = 0;
  this.increase = function () {
    return ++count;
  };
}

// 프로토타입에 메서드 추가 가능
Counter.prototype.sayHello = function () {
  console.log("Hello!");
};

const counter = new Counter();
counter.sayHello(); // "Hello!" 출력

// 일반 함수는 프로토타입 체인 사용 불가
const regularCounter = createCounter();
// regularCounter.sayHello(); // Error!
  1. 메모리 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 프로토타입을 이용한 메모리 효율적인 방법
function CounterEfficient() {
    let count = 0;
    this.getCount = function() { return count; };
}

// 공통 메서드는 프로토타입에 정의
CounterEfficient.prototype.increase = function() {
    return ++this.getCount();
};

const counter1 = new CounterEfficient();
const counter2 = new CounterEfficient();
// increase 메서드는 프로토타입에서 공유됨

정리

  1. 일반 함수 클로저의 장점
  • 더 간단하고 직관적
  • 객체 리터럴을 반환하므로 구현이 명확
  • private 데이터 캡슐화가 자연스러움
  1. new 생성자 함수의 장점
  • 프로토타입을 통한 메서드 공유 가능
  • instanceof 연산자 사용 가능
  • 생성자 함수임을 명확히 알 수 있음
  • this를 통한 확장성이 좋음
  1. 사용 시기
  • 단순한 클로저가 필요할 때 → 일반 함수
  • 인스턴스 생성과 프로토타입 상속이 필요할 때 → new 생성자 함수
  • 메모리 효율성이 중요할 때 → new 생성자 함수 + 프로토타입