1、AMD簡介
AMD,全稱 Asynchronous Module Definition,即異步模塊加載機制。AMD 規範非常簡單隻有一個API,即 define 函數:
define([module-name?],[array-of-dependencies?],[module-factory-or-object]);
其中,
- module-name:模塊標識,可以省略
- array-of-dependencies:所依賴的模塊數組,可以省略
- module-factory-or-object:模塊的實現或者一個 JavaScript 對象
define 函數具有異步性,其首先會異步加載第二個參數中列出的依賴模塊,當所有的模塊被加載後,執行第三個參數的回調函數。
2、define 函數使用
(1)三個參數
define("A", ["require", "exports"], function(require, exports){
export.fun = function(){
return require("B").fun;
}
});
上述代碼定義了一個 A 模塊,並且依賴於內置的 require,exports 模塊,第三個參數是回調函數,可以直接使用依賴的模塊,他們按依賴聲明順序作爲參數提供給回調函數。
require 函數是用來模塊依賴,即獲取模塊的引用,即使模塊沒有作爲參數定義,也能夠被使用;exports 定義 A 模塊實體,在其上定義的任何屬性和方法就是 A 模塊的屬性和方法。通過 exports.fun= … 就是爲 A 模塊定義了一個 fun 方法。
(2)兩個參數
define 函數允許省略第一個參數,因此定義一個匿名模塊。這時候模塊文件的文件名就是模塊標識,即如果這個模塊文件名爲 A.js ,那麼 A 就是模塊名。可以在依賴項目中用 A 來依賴於這個匿名模塊。這將帶來一個好處,就是模塊的高度可重用的。你拿來一個匿名模塊,隨便放在一個位置就可以使用它,模塊名就是它的文件路徑。這也很好的符合了 DRY(Don’t Repeat Yourself)原則。
define(['A'], function(A){
return {
fun: function(){
return A.fun() + 2;
}
};
});
(3)一個參數
define 的前面兩個參數都可以省略;第三個參數有兩種情況:一鍾是 JavaScript 對象,另一種是一個函數。
如果是對象,可以是包含方法的對象或者是隻提供數據。後者和 JSONP非常類似,因此,AMD可以認爲包含了一個完整的JSONP實現。模塊演變爲一個簡單的數據對象,這樣的數據對象是高度可用的,而且因爲是靜態對象,它也是CDN友好的,可以提高JSONP的性能。
如果是函數,其用途之一是快速開發實現。適用於較小型的應用,該方式無需提前考慮需要引入的模塊,只需使用時,require 即可。
define(function(){
var a = require("A");
})
define函數在執行的時候,會調用函數的 toString 方法,並掃描其中的 require 調用,提前載入這些模塊,載入完成後再執行。
注意:Opera 不能很好的支持函數的 toString 方法,因此,在瀏覽器中它的適用性並不強。但是使用構建工具打包時,構建工具會掃描 require 並強制載入依賴模塊。
3、AMD 與 CMD 的區別是:
- AMD 是提前執行,CMD 是推遲執行,
CMD 推崇依賴就近,AMD推崇依賴前置。
即 CMD:define(function(require, exports, module){ var a = require('./a); a.doSomething(); var b = require('./b'); b.doSomething(); })
AMD:
define(['./a','./b'], function(a, b){})