- commonJs模块输出的是一个值的拷贝,es6模块输出的是值的引用 commonjs模块输出的是一个值的拷贝,也就是说一旦输出,内部再变化都影响不到输出的值。请看下面的例子
main.js
var counter = 3;
function incCounter() {
counter++;
}
module.exports = {
counter: counter,
incCounter: incCounter,
};
上面代码输出counter变量和改写变量的内部方法incCounter
index.js
var mod = require('./main.js');
console.log(mod.counter); // 3
mod.incCounter();
console.log(mod.counter); // 3
上面代码说明main.js加载以后,内部的变化时不影响外面输出的值的,内部输出的值会被缓存,下次再调用的时候走的是缓存。
// 这是commonJS源码处理缓存的方式
if(Module._cache[filename]){ // 如果存在这个值直接将exports返回即可,不会重新取值
return Module._cache[filename].exports;
}
commonjs要想得到内部变动后的值只能写成一个函数
var counter = 3;
function incCounter() {
counter++;
}
module.exports = {
get counter () {
return counter
},
incCounter: incCounter,
};
上面代码输出的是一个取值器,再执行index.js就可以正确读取内部变量的变动。
index.js
3
4
es6模块输出的是值的引用,JS引擎对脚本静态解析的时候遇到模块加载命令import,就会生成一个只读引用,等到脚本真正执行时,再根据这个只读引用,到被加载的模块中去取值。
test.js
var userName = '0000';
function sayHi() {
userName = '313131'
}
export {userName, sayHi};
index.js
import {userName ,sayHi} from './test.js';
console.log(userName); // 3
sayHi();
console.log(userName); // 4
上面代码中,es6模块输出的就是一个值的引用,不会缓存运行的结果,而是动态的去被加载的模块中取值
- esModule 不能放在代码块中,只能放在顶层作用域中。
- esModule 中的import();是异步加载,commonJS的require是同步加载。
- commonJS模块是运行时加载,es6模块是编译时输出接口。