네임스페이스 패턴
- 프로그램에서 필요로 하는 전역 변수의 개수를 줄이는 동시에, 접두어를 사용하지 않고도 이름이 겹치지 않게 해준다.
- 자바스크립트에 네임스페이스라는 함수는 없지만, 별도로 구현할 수 있다.
// 네임스페이스 함수를 사용한다.
MYAPP.namespace('MYAPP.modules.module2');
// 결과 반환
var MYAPP = {
module: {
module2: {}
}
};
- namespace() 를 구현한 예제
- namespace는 자바스크립트의 예약어이다. 쓰지 않는 것을 권한다.
var MYAPP = MYAPP || {};
MYAPP.namespace = function (ns_string) {
var parts = ns_string.split('.'),
parent = MYAPP, i;
// 처음에 중복되는 전역 객체명은 제거한다
if (parts[0] === "MYAPP") {
parts = parts.slice(l);
}
for (i = 0; i < parts.length; i += 1) {
// 프로퍼티가 존재하지 않으면 생성한다.
if (typeof parent[parts[i]] === "undefined") {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
};
의존 관계 선언
- 자바스크립트 라이브러리들은 대개 네임스페이스를 지정하여 모듈화 되어 있다.
- 이 때 함수나 모듈 내 최상단에 의존 관계에 있는 모듈을 선언하는 것이 좋다.
// YUI 라이브러리 예시
// YAHOO.util.Event, YAHOO.util.Dom 같은 모듈이 추가되어 있다고 할 때
var myFunction = function() {
// 의존 관계에 있는 모듈들을 지역변수로 선언하고,
var event = YAHOO.util.Event,
dom = YAHOO.util.Dom;
// 이제 event와 dom이라는 변수를 사용한다.
};
의존 관계 선언 시 장점
- 명시적으로 선언되어 있어 코드를 사용하는 사람이 페이지 내에 포함시켜야 하는 스크립트 파일이 무엇인지 알 수 있다.
- 지역 변수(dom)은 전역 변수(YAHOO.util.Dom)보다 호출이 빠르다. (전역 객체 판별을 단 한번만 수행하기 때문.)
비공개 프로퍼티와 메서드
- 자바스크립트는 private, protected, public 접근 제한자가 없지만
- 클로저를 사용해서 private를 구현할 수 있다.
모듈 패턴
- 자바스크립트에 별도로 모듈 패턴이라는 패턴이 있는 것이 아니라, 다음 패턴 여러 개를 조합한 것이다.
- 네임스페이스 패턴
- 즉시 실행 함수
- 비공개 멤버와 특권 멤버
- 의존 관계 선언
- 네임스페이스를 설정
MYAPP.namespace('MYAPP.utilities.array');
- 모듈 정의
MYAPP.utilities.array = (function () {
return {
// 여기에 객체 내용을 구현한다...
};
}());
- 공개 인터페이스에 메서드 추가
MYAPP.utilities.array = (function () {
return {
inArray: function (needle, haystack) {
// ...
},
isArray: function (a) {
// ... }
};
}());
즉시 실행 함수가 반환하는 최종 결과는 모듈의 공개 API를 담은 객체이다.
MYAPP.namespace('MYAPP.utilities.array');
MYAPP.utilities.array = (function () {
// 의존관계
var uobj = MYAPP.utilities.object,
ulang = MYAPP.utilities.lang,
// 비공개 프로퍼티
array_string = "[object Array]", ops = Object.prototype.toString;
// 비공개 메서드들
// ...
// var 선언을 마친다.
// 필요하면 일회성 초기화 절차를 실행한다.
// ...
// 공개 API
return {
inArray: function (needle, haystack) {
for (var i = 0, max = haystack.length; i < max; i += 1) {
if (haystack[i] === needle) {
return true;
}
}
},
isArray: function (a) {
return ops.call(a) === array_string;
}
// ... 더 필요한 메서드와 프로퍼티를 여기 추가한다.
};
}());