[JavaScript]
기초
- [JS] Js기초
- [JS] Js기초 변수
- [JS] Js기초 자료형
- [JS] Js기초 형변환
- [JS] Js기초 연산자
- [JS] Js기초 반복문
- [JS] Js기초 switch
- [JS] Js기초 function
- [JS] Js기초 객체
- [JS] Js기초 배열
중급
- [JS] Js중급 호이스팅(Hoisting)과 TDZ(Temporal Dead Zone)
- [JS] Js중급 생성자함수
- [JS] 객체 메소드(Object methods), 계산된 프로퍼티(Computed property)
- [JS] 심볼(Symbol)
- [JS] WeakMap WeakSet
- [JS] 숫자, 수학 method (Number, Math)
- [JS] 문자열 메소드(String methods)
- [JS] 배열 메소드(Array methods)
- [JS] 구조 분해 할당 (Destructuring assignment)
- [JS] 매개변수 리스트와 전개 문법(Rest parameters and spread syntax)
- [JS] 클로저(Closure)
- [JS] setTimeout / setInterval
- [JS] call / apply / bind
- [JS] 상속, 프로토타입(Prototype)
- [JS] 클래스(Class)
- [JS] 클로미스(Promise)
- [JS] 비동기 처리(Async/Await)
- [JS] Generator
- [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 (독립적인 스코프)
주요 차이점
- 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
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
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 메서드는 프로토타입에서 공유됨
정리
- 일반 함수 클로저의 장점
- 더 간단하고 직관적
- 객체 리터럴을 반환하므로 구현이 명확
- private 데이터 캡슐화가 자연스러움
- new 생성자 함수의 장점
- 프로토타입을 통한 메서드 공유 가능
- instanceof 연산자 사용 가능
- 생성자 함수임을 명확히 알 수 있음
- this를 통한 확장성이 좋음
- 사용 시기
- 단순한 클로저가 필요할 때 → 일반 함수
- 인스턴스 생성과 프로토타입 상속이 필요할 때 → new 생성자 함수
- 메모리 효율성이 중요할 때 → new 생성자 함수 + 프로토타입