객체생성패턴

객체 생성 패턴

네임스페이스 패턴

비공개 프로퍼티와 메서드

비공개 멤버와 특권 멤버

모듈 패턴

다음의 패턴들 여러개를 조합.

  • 네임 스페이스 패턴
  • 즉시 실행 함수
  • 비공개 멤버와 특권 멤버
  • 의존 관계 선언
1
2
  • 모듈 노출 패턴

  • 생성자를 생성하는 모듈

  • 모듈에 전역 변수 가져오기

샌드박스 패턴.

네임스페이스 패턴의 단점을 보완

  • 전역 객체가 단 하나의 전역변수에 의존한다.
    따라서 동일한 애플리케이션이나 라이브러리의 두 가지 버전을 한 페이지에서 실행시키는 것이 불가능 하다.
    전역변수 명이 모두 하나이기 때문.
  • MYAPP.utilities.array 와 같이 점으로 연결된 긴 이름을 써야 하고 런타임에는 탐색 작업을 거쳐야 한다.

전역 생성자

네임스페이스 패턴에서는 전역 객체가 하나다. 샌드박스 패턴의 유일한 전역은 생성자다.
생성자에 콜백 함수를 전달해 해당 코드를 샌드박스 내부 환경으로 격리시킨다.

1
2
3
new Sandbox( function(box) {
// coding...
});

box 객체는 네임스페이스 패턴에서 MYAPP과 같은 것이다. 코드가 동작하는데 필요한 모든 라이브러리 기능이 여기에 들어간다.

패턴에 추가해 보기

  • new 강제한다. new를 쓰지않아도 자동으로 처리
  • Sandbox() 생성자가 선택적인 인자를 하나 이상 받을 수 있게 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Sandbox( ['ajax', 'event'], function(box) ) {
// coding...
});
Sandbox( 'ajax', 'event', function(box) ) {
// coding...
});
// 모든 모듈을 사용한다는 의미로 '*'이나, 생략도 생각해 볼 수 있다.
Sandbox( '*', function(box) ) {
// coding...
});
Sandbox( function(box) ) {
// coding...
});
// 샌드박스 객체의 인스턴스를 여러 개 만드는 예제.
Sandbox( 'dom', 'event', function(box) ) {
// dom과 event를 가지고 작업하는 코드
Sandbox( 'ajax', function(box) ) {
// 샌드박스된 box 객체를 또 하나 만든다.
// 이 'box' 객체는 바깥쪽 함수의 'box' 객체와는 다르다.
// ...
// ajax를 사용하는 작업 완료
});
// ajax 모듈의 흔적이 없어진.
});

샌드박스 패턴을 사용하면 콜백 함수로 코드를 감싸기 때문에 전역 네임스페이스를 보호할 수 있다.

샌드박스 패턴 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/** 생성자 구현 **/
function Sandbox() {
var args = Array.prototype.slice.call(arguments),
// 마지막 인자는 콜백함수
callback = args.pop(),
modules = ( args[0] && typeof args[0] === 'string' ? args : args[0] ),
i;
// 함수가 생성자로 호출되도록 보장한다.
if ( !(this instanceof Sandbox) ) {
return new Sandbox(modules, callback);
}
// this에 필요한 프로퍼티들을 추가 한다.
this.a = 1;
this.b = 2;
// 코어 this 객체에 모듈을 추가한다.
// 모듈이 없거나 * 이면 사용 가능한 모든 모듈을 사용한다는 의미.
if ( !modules || modules === '*' || modules[0] === '*' ) {
modules = [];
console.log(Sandbox.modules);
for ( i in Sandbox.modules ) {
console.log(1);
if ( Sandbox.modules.hasOwnProperty(i) ) {
console.log(2);
modules.push(i);
}
}
}
// 필요한 모듈을 초기화 한다.
for ( i = 0; i < modules.length; i += 1 ) {
Sandbox.modules[modules[i]](this);
}
// 콜백함수 호출
callback(this);
Sandbox.prototype = {
name : 'MyApp',
version : '1.0',
getName : function() {
return this.name;
}
}
}
/** 모듈추가 **/
Sandbox.modules = {}
Sandbox.modules.dom = function(box) {
box.getElement = function(){
console.log('getElement');
};
box.getStyle = function(){
console.log('getStyle');
};
box.foo = 'bar';
}
Sandbox.modules.event = function(box) {
// 필요에 따라 다음과 같이 Sandbox 프로토타입에 접근할 수 있다.
// box.constructor.prototype.m = 'mmm';
box.attachEvent = function(){
console.log('attachEvent');
};
box.detachEvent = function(){
console.log('detachEvent');
};
}
Sandbox.modules.ajax = function(box) {
box.makeRequest = function(){
console.log('makeRequest');
};
box.getResponse = function(){
console.log('getResponse');
};
}
Sandbox(['ajax', 'event'], function(box) {
box.attachEvent();
box.makeRequest();
});

스태틱 맴버

공개 스태틱 맴버

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 생성자
var Gadget = function() {};
// 스태틱 메서드
Gadget.isShiny = function() {
return 'you bet';
}
// 프로토타입에 일반적인 함수를 추가한다.
Gadget.prototype.setPrice = function(price) {
this.price = price;
};
// 프로토타입에 일반적인 메서드를 추가한다.
Gadget.prototype.isShiny = function() {
return Gadget.isShiny.call(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
25
26
27
28
29
30
31
32
var Gadget = (function() {
var counter = 0;
return function() {
console.log(++counter);
}
}());
// getLastId() 추가
var Gadget = (function() {
var counter = 0,
NewGadget;
NewGadget = function() {
counter += 1;
};
NewGadget.prototype.getLastId = function() {
return counter;
};
// 생성자를 덮어 쓴다.
return NewGadget;
}());
var a = new Gadget();
a.getLastId();
var b = new Gadget();
b.getLastId();

객체 상수 ( es6 const )

체이닝 패턴

method() 메서드

1
2
3
4
5
6
if ( typeof Function.prototype.method !== 'function' ) {
Function.prototype.method = function (name, implementation) {
this.prototype[name] = implementation;
return this;
};
}
Share