2011-10-02 22 views
9

我想更好地組織我的JavaScript。我的目標是擁有模塊化體系結構,我可以分解成單獨的文件(sitename.js,sitename.utils.js等)。這兩個JavaScript模式有什麼區別

我想知道這兩種模式的優點和缺點,哪一種更適合打入生活在單獨文件中的模塊。

模式#1(模塊圖案)

var MODULE = (function() { 

    //private methods 

    return { 
     common: { 
      init: function() { 
       console.log("common.init"); 
      } 
     }, 
     users: { 
      init: function() { 
       console.log("users.init"); 
      }, 
      show: function() { 
       console.log("users.show"); 
      } 
     } 
    } 
})(); 

模式#2(單)

var MODULE = { 
    common: { 
    init: function() { 
     console.log("common.init"); 
    } 
    }, 

    users: { 
    init: function() { 
     console.log("users.init"); 
    }, 

    show: function() { 
     console.log("users.show"); 
    } 
    } 
}; 
+0

首先想到的是模式1允許初始化代碼,它可能包含立即超出範圍的變量或函數聲明,因此不會污染封閉範圍。 – Pablo

回答

8

個人而言,我建議的#1的延伸,如下:

var Module = (function(Module) { 
    // A comment 
    Module.variable1 = 3; 

    /** 
    * init() 
    */ 
    Module.init = function() { 
    console.log("init"); 
    }; 

    // ... 

    return Module; 
})(Module || {}); 

由於幾個原因,我喜歡這種模式。其中一個文檔(特別是javadoc風格)看起來更自然,當你的所有函數都是聲明而不是大散列時。二,如果你的子模塊的規模增長,它可以讓你把它們分解成多個文件而不需要任何重構。

例如,如果Module.Users人進入自己的文件:

var Module = Module || {}; 
Module.Users = (function(Users) { 
    /** 
    * init() 
    */ 
    Users.init = function() { 
    console.log("Module.Users.init"); 
    }; 

    // ... 

    return Users; 
})(Module.Users || {}); 

現在「module.js」和「module.users.js」可以是單獨的文件,它們會工作不管他們加載的順序如何。還請注意模塊名稱的本地範圍 - 如果您的模塊名稱很長,這非常方便,因爲您可以在模塊定義的範圍內使用「MyApp.Users.EditScreen」並使用類似「ES」的變量引用它。

+0

新模式還允許以其他方式增加模塊。在[本站]上有一篇關於javascript模塊的非常好的文章(http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth) – NT3RP

+0

這很好,但我得到一個錯誤 - http: //jsfiddle.net/rjFHB/或者我正在以錯誤的方式初始化Module.Users。 – howtodothis

+1

這是我的錯誤 - 「Module.Users」不應該在它前面有一個變量(因爲全局的Module已經被定義)。我會編輯它。 –

2

第一種模式允許通過閉包的私有變量,方法等。例如:

var MODULE = (function() { 

    var privateStuff = 'This is private'; 

    var doStuff = function(obj) { 
     console.log('Doing stuff...'); 
     console.log(privateStuff); 
    }; 

    return { 
     common: { 
      init: function() { 
       console.log("common.init"); 
       doStuff(this); 
      } 
     }, 
     users: { 
      init: function() { 
       console.log("users.init"); 
      }, 
      show: function() { 
       console.log("users.show"); 
      } 
     } 
    } 
})(); 

privateStuffdoStuff不是對象的性質,而不是提供給什麼,但什麼返回MODULE定義在函數內部。因此,展示如何使用#2來做到這一點的例子是不可能的。

JS沒有私有成員的概念,所以你不能通過常規的對象字面值來定義它們。所以如果你需要私人的東西,去第一個選擇。如果你不這樣做,#2更簡單。

1

你寫的代碼幾乎是一樣的。但是,隨着代碼的發展,第一種形式更容易處理,因爲它允許您添加私有變量和函數。第二種形式不支持這一點,而且你幾乎總是最終想要第一種形式。