模块是比对象和函数更大的代码单元,使用模块可以将程序进行归类。
ES6模块并未被所有浏览器所兼容,虽然这只是时间问题,但实际工程中还需使用 Bable、Webpack 等工具进行转码。
常见的几种 JavaScript 模块化规范
- AMD
- CommonJS
- ES6
// 使用函数作为模块,jQuery也使用此方法
(function() {
var numClicks = 0;
document.addEventListener('click', function() {
console.log(numClicks++);
})
})();
AMD 的设计明确基于浏览器
AMD 可以很容易指定模块及其依赖关系。同时,它支持浏览器。
AMD 有以下几项优点:
- 自动处理依赖,我们无需考虑模块引入顺序
- 异步加载模块,避免阻塞
- 在同一个文件中可以定义多个模块
// AMD模式
define('MouseCounterModule', ['jQuery'], function($) {
var numClick = 0;
var handleClick = function() {
console.log(numClick++);
}
return {
countClicks: function() {
$(document).on('click', handleClick);
}
}
})
CommonJS 的设计是面向通用 JavaScript 环境,例如 node.js 服务器
CommonJS 要求一个文件是一个模块,因此不用担心模块中定义的变量会造成全局污染
CommonJS 具有两个优势:
- 语法简单
- 是 Node.js 默认的模块格式,我们可以使用 npm 上成千上万的包
CommonJS 最大的缺点是不显示地支持浏览器,需要代码转换工具转换为浏览器支持格式
// 这里该模块的文件名为: MouseCounterModule.js
const $ = require('jQuery');
let numClick = 0;
const handleClick = () => {
console.log(numClick++);
}
module.exports = {
countClicks: () => {
$(document).on('click', handleClick);
}
}
// 在另一个文件中引用上面的模块
const MouseCounterModule = require('MouseCounterModule.js');
MouseCounterModule.countClicks();
ES6 模块结合了 CommonJS 与 AMD 的优点:
- 语法简单,基于文件
- 支持异步模块加载
ES6 模块关键字
-
export
从模块外部指定标识符 -
import
导入模块标识符
export
- 命名导出 对导出多个值很有用。在导入期间,必须使用相应对象的相同名称。
- 默认导出 一个文件中只能有一个,可以使用任何名称导入默认导出
// 命名导出
// 文件 my-module.js
function foo() {
console.log('foo');
}
const bar = 'bar';
export { foo, bar };
// 导入方式
import { foo, bar } from 'my-module.js';
console.log(foo()); // 'foo'
console.log(bar); // 'bar'
// 默认导出
// 文件 my-module.js
export default function() {
console.log('I am default module');
}
// 导入方式
import fn from 'my-module.js';
console.log(fn()); // I am default module
import
// 导入整个模块内容
import * as myModule from '/modules/my-module.js';
myModule.foo();
myModule.bar;
// 导入单个或多个导出
import { foo, bar } from 'my-module.js';
// 导入并重命名
import { myFoo as foo, myBar as bar } from 'my-module.js';
无绑定导入,作为此模块的全局代码
// 文件my-module.js
Array.prototype.pushAll = function(items) {
if(!Array.isArray(items)) {
throw new TypeError('参数必须是一个数组!');
}
return this.push(...items);
}
// 无绑定导入
import myDefault from 'my-module.js'
let colors = ['red', 'green', 'blue'];
let items = [];
items.pushAll(colors);
加载模块
<script type="module" src="./my-module.js"></script>
网友评论