在JavaScript模組到底是什麼,能用代碼具體展現一下嗎?
其實上一篇已經寫了一段事件模組代碼
event = function() {// do morereturn {bind: function() {},unbind: function() {},trigger: function() {}};}();
這能代表“模組”嗎?這就是一個JS對象啊,以為有多麼深奧。
是的,JavaScript中模組多數時候被實現為一個對象。這麼看來,多數時候我們都寫過“模組”(但沒有在整個項目中應用模組化思想)。或許每個人寫模組的方式(風格)還不同。比如上面的事件模組是一個匿名函數執行,匿名函數中封裝了很多代碼,最後通過return返回給event變數,這個event就是事件模組的介面。
又如jQuery,它也是一個匿名函數執行,但它並不返回介面對象。而是將自己暴露給window對象。
(function(window){// ..// exportswindow.jQuery = window.$ = jQuery;})(window);
再如SeaJS,它一開始就將介面公開了
/** * Base namespace for the framework. */this.seajs = { _seajs: this.seajs };
後續是很多的匿名函數執行給變數seajs添加很多工具方法。注意,這裡的this在瀏覽器環境指window對象,如果是定位在瀏覽器中,這個this也可以去掉。就象Ext。
Ext = { /** * The version of the framework * @type String */ version : '3.1.0'};
呃,我們已經看到了四種方式寫模組(把jQuery,SeaJS,Ext看成模組,呃很大的模組)。
哪一種更好呢? 哪一種更適合在瀏覽器端呢?純從代碼風格上說,是蘿蔔白菜各有所愛。只要我們運用了“模組化”的思想來開發就行了。
但如果有一種統一的文法格式來寫模組豈不是更好,就不會出現各用各的風格來寫模組而使代碼亂糟糟。
這就是目前的現狀,開發人員強烈需要一種統一的風格來寫模組(最好是語言內建了)。這時一些組織出現了,最具代表的如CommonJS,AMD。此外ECMAScript也開始著手模組的標準化寫法。
無論它們提供什麼樣的寫法,我們需要的僅僅是
1,將一些零散代碼封裝成一個有用的單元(encapsulate)
2,匯出模組的介面API(exports)
3,方便友好引用其它模組(dependency)
伺服器端的JSer是幸運的,它有Node.js,Node.js遵循了一個稱為CommonJS的規範。CommonJS其中就有對寫模組的標準化。當然模組化只是其中的一部分而已。具體來說Node.js實現了
- Modules/1.0
- Promises/B (http://github.com/kriskowal/q)
- Promises/D (https://github.com/kriskowal/q)
- Unit Testing/1.0
模組化方面它實現了Modules/1.0(已經更新到1.1.1)。 以下是node中是寫模組的一個樣本。
math.js
exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) { sum += args[i++]; } return sum;};
increment.js
var add = require('math').add;exports.increment = function(val) { return add(val, 1);};
main.js,該檔案為入口檔案
var inc = require('increment').increment;var a = 1;inc(a); // 2
這就寫了一個math、increment、main模組。math提供了add方法來實現數字相加。increment模組依賴於math模組,它提供increment方法實現相加。main擷取到increment方法,執行相加操作。
以上程式碼範例可以看到
1,node要求一個js檔案對應一個模組。可以把該檔案中的代碼想象成是包在一個匿名函數中,所有代碼都在匿名函數中,其它模組不可訪問除exports外的私人變數
2,使用exports匯出API
3,使用require載入其它模組
CommonJS module基本要求如下1,標示符require,為一個函數,它僅有一個參數為字串,該字串須遵守Module Identifiers的6點規定2,require方法返回指定的模組API3,如果存在依賴的其它模組,那麼依次載入4,require不能返回,則拋異常5,僅能使用標示符exports匯出API
Modules/1.1較1.0僅增加了標示符module,require函數增加了main和paths屬性。而仔細比對1.1與1.1.1後發現除了格式調整了下幾乎沒有變化。
相關:
Modules
Modules/1.0
Modules/1.1
Modules/1.1.1
下一篇:Node.js模組格式在瀏覽器中的嘗試