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){})