1、export 在接口名字与模块内部的变量之间建立了一一对应的关系,export输出的接口,与其模块内对应的变量值是动态绑定的,即通过暴露的接口可以取到模块内与之对应绑定变量的实时的值。
commonjs的规范完全不同,commonjs输出的是值的缓存,不存在动态的更新。
export var firstName = 'Michael'; export var lastName = 'Jackson'; export var year = 1958;
export
的写法,除了像上面这样,还有另外一种。
// profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export { firstName, lastName, year };
export
命令除了输出变量,还可以输出函数或类(class)。
export function multiply(x, y) { return x * y; };
2、CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。
/ CommonJS模块 let { stat, exists, readFile } = require('fs'); // 等同于 let _fs = require('fs'); let stat = _fs.stat; let exists = _fs.exists; let readfile = _fs.readfile;
上面代码的实质是整体加载fs
模块(即加载fs
的所有方法),生成一个对象(_fs
),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。
// ES6模块 import { stat, exists, readFile } from 'fs';
ES6 模块不是对象,而是通过export
命令显式指定输出的代码,再通过import
命令输入。上面代码的实质是从fs
模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。
tips:import
语句会执行所加载的模块,因此可以有下面的写法。
import 'lodash';
上面代码仅仅执行lodash
模块,但是不输入任何值。