AMD全称是Asynchronous Modules Definition异步模块定义,提供定义模块及异步加载该模块依赖的机制,这和浏览器的异步加载模块的环境刚好适应(浏览器同步加载模块会导致性能、可用性、调试和跨域访问等问题)。
AMD规范只定义了一个函数 "define",它是全局变量。模块通过 define 函数定义在闭包中,格式如下:
define(id?: String, dependencies?: String[], factory: Function|Object);
id 是模块的名字,是个字符串,这个参数是可选的。如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名字)。
模块名的格式:模块名用来唯一标识定义中模块,它们同样在依赖数组中使用。AMD的模块名规范是CommonJS模块名规范的超集。引用如下:
上面所说到的CommonJS模块id属性常被用于JavaScript模块。 相对模块名解析示例:
dependencies 是个定义中模块所依赖模块的数组。依赖模块必须根据模块的工厂方法优先级执行,并且执行的结果应该按照依赖数组中的位置顺序以参数的形式传入(定义中模块的)工厂方法中。
依赖的模块名如果是相对的,应该解析为相对定义中的模块。换句话来说,相对名解析为相对于模块的名字,并非相对于寻找该模块的名字的路径。
AMD规范定义了三种特殊的依赖关键字。如果"require","exports", 或 "module"出现在依赖列表中,参数应该按照CommonJS模块规范自由变量去解析。
依赖参数是可选的,如果忽略此参数,它应该默认为["require","exports","module"]。然而,如果工厂方法的形参个数小于3,加载器会选择以函数指定的参数个数调用工厂方法。
define(function(require, exports, module) {})
factory 是最后一个参数,它包裹了模块的具体实现,它是一个函数或者对象。如果是函数,那么它的返回值就是模块的输出接口或值。
定义一个名为 myModule 的模块,它依赖 jQuery 模块:
define('myModule', ['jquery'], function($) {
// $ 是 jquery 模块的输出
$('body').text('hello world');
});
// 使用
require(['myModule'], function(myModule) {});
定义一个没有依赖性的模块可以直接定义对象:
define({
add: function(x, y){
return x + y;
}
});
因为没有定义模块名称,所以上述方式保存到js文件以后,使用时require的模块依赖就是该js文件的名字