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:
AMD:define(function(require, exports, module){ var a = require('./a); a.doSomething(); var b = require('./b'); b.doSomething(); })
define(['./a','./b'], function(a, b){})