본문 바로가기

Web/Javascript

A JavaScript Module Pattern

Module Pattern은 작년 6월에 이야기가 나온것이다..
작년 6월이라하면... 한참 ASP가지고 씨름을 하고 있는... 그야말로 초보의 생초보...

프로그램의 개념도 안가지고 있고 그저 단순히 Copy & Paste 만 죽어라 하고 있을때다..
Javascript 공부는 하고 있었지만 그 실력이라는 것은 그야말로 최하급..

그런그때 이야기가 나온것을 나는 2달전에야 이런 패턴이 있다는것을 알았고
(ExtJs 공부하면서..물론 prototype.js 1.6.0 버전에도 있다 그 전에도 있나?)
이것이 Eric씨가 A JavaScript Module Pattern 이라고 지었다는것을 어제 알았다...

아무튼 내가 얼마나 시대에 뒤떨어져 살아가는지 충분히 깨닳게 해준 글이었던거 같다.

그래서 A JavaScript Module Pattern 을 정리해 보고자 한다.

기존에 클래스를 만드는 방식은
var Hoge = function (){ 
    this.name = name; 
 this.tall = tall; 
   } 
Hoge.prototype = { 
     alertA: function() { 
          alert(this.name);   
          alert(this.tall); 
     } 
} 
var hoge = new Hoge('홍길동','180cm'); 
hoge.alertA();

위와 같았다.

위와 같은 표기는 Javascript 에서 클래스를 만드는 대표적인 방법이다.
생성자와 메소드로 나뉘어서 클래스화 하면 보기에도 좋고 소스가 깔끔해진다.

하지만 Javascript 에서 무분별하게 new 연산자를 난발하는 것은 메모리를 많이 잡는다.
new 연산자로 인스턴스를 만들게 되면 prototype 오브젝트를 쓸데없이 전부 가져가게 되는 것이다.
(new 연산자의 낭비에 관해서는 다음 포스팅에)

이로인해 YUI에서는 (ExtJs도) 싱글톤 패턴을 지향한 Javascript Module Pattern 이라는 것을 쓴다.
계속 보자..

1. 네임스페이스 오브젝트를 만들자.
    YUI나 ExtJS에서는 namespace 라는 메소드가 있어 YAHOO 오브젝트와 Ext 오브젝트에 원하는 이름의 오브
   젝트를 만들어준다.
   말이 namespace 이지 그냥 빈 오브젝트이다.
   원래는

YAHOO.namespace("myProject"); Ext.namespce("myProject"); 위의 2개를 써야하지만.. 그냥 myProject = {}; 이렇게 해도 상관이 없다. 다만 myProject가 전에 선언되지 않은 오브젝트이어야 한다.


2. namespace 로 지정해준 오브젝트의 익명함수 return 값을 할당한다.
Ext.myProject.myModule 또는 myProject.myModule 이렇게 위에서 선언한 값으로 해도 된다.
하지만 YAHOO Blog에 포스팅 된것이라 맞춰서 하겠다.

YAHOO.myProject.myModule = function () {
          return  {
               myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty.";
               myPublicMethod: function () {
                    YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
               }
          };
}(); // 이곳의 괄호는 익명함수의 return 문을 실행시킨다.


마지막 줄의 괄호()는 끝임을 보강한다. 이 기호는 익명함수  return 안의 오브젝트 myPublicProperty 와 myPublicMethod를 즉시 실행시킨다. 익명함수의 return들과 같이 YAHOO.myProject.myModule의
return 오브젝트와 같다.

3. “private” 메소드 그리고 변수는 익명함수에서 return 문 앞에 쓴다.

YAHOO.myProject.myModule = function () {

  //"private" variables:
                var myPrivateVar = "I can be accessed only from within YAHOO.myProject.myModule.";

  //"private" method:
                var myPrivateMethod = function () {
  YAHOO.log("I can be accessed only from within YAHOO.myProject.myModule");
                 }

  return  {
                             myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty."
               myPublicMethod: function () {
                             YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");

  //Within myProject, I can access "private" vars and methods:
  YAHOO.log(myPrivateVar);
  YAHOO.log(myPrivateMethod());

  //The native scope of myPublicMethod is myProject; we can
  //access public members using "this":
  YAHOO.log(this.myPublicProperty);
                               }
  };
}();





위와같이 Private 메소드와 변수를 선언할 수 있다.
코드 블럭안의 함수의 return 문에 2개 멤버의 오브젝트를 가진다.
이 멤버들은 YAHOO.myProject.myModule 에서 this.myPublicProperty 그리고 this.myPublicMethod 로 주소를 갖는다.
외부에서 접근할 수 있는 Public 멤버들의 접근은
YAHOO.myProject.myModule.myPublicProperty and YAHOO.myProject.myModule.myPublicMethod.
이다.

Private 변수는 myPrivateProperty 그리고 myPrivateMethod 로서 오직 익명 함수 그자신 안의 return 오브젝트 멤버에서 접근가능하다.
그것은 강력한 closure를 통하여 익명함수의 결과와 즉시 실행에도 불구하고 함수의 return 후에 로컬 변수의 유지를 제한한다. YAHOO.myProject.myModule이 그것들을 필요로 하는 것처럼 2개의 private변수들을 없애지 않는다.