ES6 模块
定义和引用
- ES6模块强制自动使用严格模式,所以不管写没写 ”use strict“ 声明都是一样的
- 虽然大部分浏览器都支持ES6语法,但script type设置为module 才能被正确解析
- 在Node.js下使用ES6语法的文件后缀名要设置为’.mjs’,用来和Node.js 默认的CommonJS模范规范来做区分
特性
ES6两个特性:一个是值引用,一个是静态声明
值引用是指export 引用输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部的值,可以简单的理解为,变量浅拷贝。
ES6对于引用声明有严格的要求,必须写在文件的首部,不允许使用变量或表达式,不允许被嵌入到其他语句中 。
静态分析是指不需要执行代码,只从字面量上对代码进行分析。
CommonJS
CommonJS规定每个文件就是一个模块,有独立的作用域。每个模块内部都有一个module对象,代表当前模块。通过它来导出api,它有以下属性:
- id 模块的识别符,通常是带有绝对路径的模块文件名
- filename 模块的文件名,带有绝对路径
- loaded 返回一个布尔值,表示模块是否已经完成加载
- parent 返回一个对象,表示调用该模块的模块
- children 返回一个数组,表示该模块用到的其他模块
- exports 表示模块对外输出的值
引用模块通过require函数,它的基本功能是,读取并执行一个javascript文件,然后返回该文件的exports对象
CommonJS的特性和es6恰恰相反,它的特性是值拷贝和动态声明 值拷贝和值引用拷贝相反,一旦使用了这个值,模块内部的变化就影响不到这个值了,可以简单的理解**”变量深拷贝“**
AMD
AMD是一种很热门的浏览器模块化方案
AMD规范只定义e了一个全局函数define,通过它可以定义和引用函数,它只有一个函数
defined(id? , despendencies?, factory )
- id 为模块的名称,默认是模块加载请求的指定脚本的名字,如果定义 就是顶级的绝对的,不允许相对名字
- dependences 是个数组,它定义了需要依赖的模块。依赖模块必须根据依赖工厂函数优先执行,按照顺序按参数的形式传入。
- factory 为模块初始化要执行的函数或对象。如果是函数,那么该函数是单例模式,只会被执行一次;如果是对象,此对象应该为模块的输出值。
由于 AMD 并不是浏览器原生支持的模块规范,所以需要借助第三方库来实现,其中最有名的就是 RequireJS
CMD
是基于浏览器环境制定的模块规范。
CMD 定义模块也是通过一个全局函数 define 来实现的,但只有一个参数,该参数既可以是函数也可以是对象:
define(factory);
如果这个参数是对象,那么模块导出的就是对象;如果这个参数为函数,那么这个函数会被传入 3 个参数 require 、 exports 和 module。
define(function(require, exports, module) {
//...
});
define(function(require, exports, module) {
var add = require('math').add;
exports.increment = function(val) {
return add(val, 1);
};
module.id = "increment";
});
CMD 最大的特点就是懒加载,它整合了 CommonJS 和 AMD 规范的特点。遵循 CMD 规范的代表开源项目是 sea.js