JavaScript模組化的理解是:1、Module模式,它透過閉包的特性開啟了一個新的作用域,緩解了全域作用域命名衝突和安全性的問題;2、CommonJS模式,主要用在Node開發上,每個檔案就是一個模組,沒個檔案都有自己的一個作用域。
JavaScript模組化的理解是:
1、Module模式
在模組化規範形成之前,JS開發者使用Module設計模式來解決JS全域作用域的污染問題。 Module模式最初被定義為一種在傳統軟體工程中為類別提供私人和公有封裝的方法。在JavaScript中,Module模式使用匿名函數自呼叫 (閉包)來封裝,透過自訂暴露行為來區分私有成員和公有成員。
let myModule = (function (window) { let moduleName = 'module' // private // public function setModuleName(name) { moduleName = name } // public function getModuleName() { return moduleName } return { setModuleName, getModuleName } // 暴露行为 })(window)
上面範例是Module模式的一種寫法,它透過閉包的特性開啟了一個新的作用域,緩解了全域作用域命名衝突和安全性的問題。但是,開發者並不能夠用它來組織和分割程式碼,於是乎便出現了以此為基石的模組化規格。
相關學習推薦:javascript影片教學
#2、CommonJS
CommonJS主要用在Node開發上,每個檔案就是一個模組,沒個檔案都有自己的一個作用域。透過module.exports
暴露public成員。例如:
// 文件名:x.js let x = 1; function add() { x += 1; return x; } module.exports.x = x; module.exports.add = add;
此外,CommonJS透過require()
引入模組依賴,require函數可以引入Node的內建模組、自訂模組和npm等第三方模組。
// 文件名:main.js let xm = require('./x.js'); console.log(xm.x); // 1 console.log(xm.add()); // 2 console.log(xm.x); // 1
從上面程式碼我們可以看出,require函數同步載入了x.js,並且傳回了module.exports輸出字面量的拷貝值。
可能有人會問module.exports.x = x;
不是賦值嗎,怎麼肥事呢?我們說,Module模式是模組化規範的基石,CommonJS也是對Module模式的一種封裝。我們完全可以用Module模式來實現上面的程式碼效果:
let xModule = (function (){ let x = 1; function add() { x += 1; return x; } return { x, add }; })(); let xm = xModule; console.log(xm.x); // 1 console.log(xm.add()); // 2 console.log(xm.x); // 1
#透過Module模式模擬的CommonJS原理,我們就可以很好的解釋CommonJS的功能了。因為CommonJS需要透過賦值的方式來取得匿名函數自呼叫的回傳值,所以require函數在載入模組是同步的。然而CommonJS模組的載入機制限制了CommonJS在客戶端上的使用,因為透過HTTP同步載入CommonJS模組是非常耗時的。
3、AMD
// 定义AMD规范的模块 define([function() { return 模块 })
區別於CommonJS,AMD
規範的被依賴模組是非同步載入的,而定義的模組是被當作回呼函數來執行的,依賴require.js
模組管理工具庫。當然,AMD規格不是採用匿名函數自呼叫的方式來封裝,我們依然可以利用閉包的原理來實作模組的私有成員和公有成員:
define(['module1', 'module2'], function(m1, m2) { let x = 1; function add() { x += 1; return x; } return { add }; })
4 、CMD
CMD 是SeaJS 在推廣過程中對模組定義的規範化產出。 AMD
推崇依賴前置,CMD
推崇依賴就近。
define(function(require, exports, module) { // 同步加载模块 var a = require('./a'); a.doSomething(); // 异步加载一个模块,在加载完成时,执行回调 require.async(['./b'], function(b) { b.doSomething(); }); // 对外暴露成员 exports.doSomething = function() {}; }); // 使用模块 seajs.use('path');
CMD整合了CommonJS和AMD的特點,支援同步和非同步載入模組。 CMD載入完某個依賴模組後並不執行,只是下載而已,在所有依賴模組載入完成後進入主邏輯,遇到require語句的時候才執行對應的模組,這樣模組的執行順序和書寫順序是完全一致的。因此,在CMD中require函數同步載入模組時沒有HTTP請求過程。
5、ES6 module
ES6的模組化已經不是規範了,而是JS語言的特性。隨著ES6的推出,AMD
和CMD
也隨之成為了歷史。 ES6模組與模組化規格相比,有兩大特點:
模組化規格輸出的是一個值的拷貝,ES6 模組輸出的是值的參考。
模組化規格是執行時期加載,ES6 模組是編譯時輸出介面。
模組化規格輸出的是一個對象,該物件只有在腳本運行完才會生成。而 ES6 模組不是對象,ES6 module 是一個多對象輸出,多對象載入的模型。從原理上來說,模組化規格是匿名函式自呼叫的封裝,而ES6 module則是用匿名函式自呼叫去呼叫輸出的成員。
以上是JavaScript模組化怎麼理解?的詳細內容。更多資訊請關注PHP中文網其他相關文章!