回想起以前的一次面试,第一轮面试官问我AMD和CMD的区别,我只回答说AMD是提早加载,CMD是按需加载。第二轮面试官又问了我CommonJS和ES6 Module的区别,emmm...,我大体回答说新的比旧的好~~,虽然面试官并无说什么,不过显然这样的答案并非有助于面试、有助于本身的技术积累的。javascript
因此有必要进行一次梳理,以便更清晰地了解它们的特色及差别。css
AMD一开始是CommonJS规范中的一个草案,全称是Asynchronous Module Definition,即异步模块加载机制。后来由该草案的做者以RequireJS实现了AMD规范,因此通常说AMD也是指RequireJS。java
经过define
来定义一个模块,使用require
能够导入定义的模块。jquery
//a.js
//define能够传入三个参数,分别是字符串-模块名、数组-依赖模块、函数-回调函数
define(function(){
return 1;
})
// b.js
//数组中声明须要加载的模块,能够是模块名、js文件路径
require(['a'], function(a){
console.log(a);// 1
});
复制代码
对于依赖的模块,AMD推崇依赖前置,提早执行。也就是说,在define
方法里传入的依赖模块(数组),会在一开始就下载并执行。webpack
CMD是SeaJS在推广过程当中生产的对模块定义的规范,在Web浏览器端的模块加载器中,SeaJS与RequireJS并称,SeaJS做者为阿里的玉伯。web
//a.js
/* * define 接受 factory 参数,factory 能够是一个函数,也能够是一个对象或字符串, * factory 为对象、字符串时,表示模块的接口就是该对象、字符串。 * define 也能够接受两个以上参数。字符串 id 表示模块标识,数组 deps 是模块依赖. */
define(function(require, exports, module) {
var $ = require('jquery');
exports.setColor = function() {
$('body').css('color','#333');
};
});
//b.js
//数组中声明须要加载的模块,能够是模块名、js文件路径
seajs.use(['a'], function(a) {
$('#el').click(a.setColor);
});
复制代码
对于依赖的模块,CMD推崇依赖就近,延迟执行。也就是说,只有到require
时依赖模块才执行。面试
CommonJS规范为CommonJS小组所提出,目的是弥补JavaScript在服务器端缺乏模块化机制,NodeJS、webpack都是基于该规范来实现的。数组
//a.js
module.exports = function () {
console.log("hello world")
}
//b.js
var a = require('./a');
a();//"hello world"
//或者
//a2.js
exports.num = 1;
exports.obj = {xx: 2};
//b2.js
var a2 = require('./a2');
console.log(a2);//{ num: 1, obj: { xx: 2 } }
复制代码
require
返回的值是被输出的值的拷贝,模块内部的变化也不会影响这个值。ES6 Module是ES6中规定的模块体系,相比上面提到的规范, ES6 Module有更多的优点,有望成为浏览器和服务器通用的模块解决方案。浏览器
//a.js
var name = 'lin';
var age = 13;
var job = 'ninja';
export { name, age, job};
//b.js
import { name, age, job} from './a.js';
console.log(name, age, job);// lin 13 ninja
//或者
//a2.js
export default function () {
console.log('default ');
}
//b2.js
import customName from './a2.js';
customName(); // 'default'
复制代码
this
指向当前模块,ES6 Module this
指向undefined
;目前浏览器对ES6 Module兼容还不太好,咱们平时在webpack中使用的export
/import
,会通过babel转换为CommonJS规范。缓存
这里比较全面的把JavaScript中的几大模块化规范罗列出来,但愿借此对JavaScript模块化有一个大体的认识,而未对细节进行具体分析,感兴趣的能够自行探索。