你所不知道的JS模块
大家应该都JS模块化有一定的了解。主流规范有两种:
- CommonJS
- ES6 Module
其中,CommonJS是Node.js官方推荐的规范。常见关键字就是require
和module.exports
而ES6 Module则是ESMAScript官方标准,常见关键字为import
和export
日常开发中,这两种规范都可能用上,因此大家有可能会忽略这两种规范之间的细微差异。本文将讲解这两种规范的一个关键差异:值的引用
相同方式
即采用相同的CommonJS或ES6 Module的方式导出和引入模块。
CommonJS导出
// 输出out.js
var a = 1;
function add(){
a++;
}
module.exports = {a, add} //ES5输出
CommonJS引入
var out = require('./out.js'); //ES5输入
console.log('before:', out.a); // before:1
out.add();
console.log('after:', out.a); // after:1
从上面的例子可以看出,通过CommonJS方式导出模块,再以同种方式引入模块,是不会改变原有模块变量的值。
我们再看看通过ES6 Module的方式导出和引入:
ES6 Module导出
// 输出out.js
var a = 1;
function add(){
a++;
}
export {a, add} // ES6输出
ES6 Module引入
import {a, add} from './out.js'; //ES6输入
console.log('before:', a); // before:1
add();
console.log('after:', a); // after:2
此时,ES6 Module的方式,就改变了原有模块的值。
不同方式
即模块的导出和引入采取不同的方式。
CommonJS导出
// 输出out.js
var a = 1;
function add(){
a++;
}
module.exports = {a, add} //ES5输出
ES6 Module引入
import {a, add} from './out.js'; //ES6输入
console.log('before:', a); // before:1
add();
console.log('after:', a); // after:1
结果可见,模块的值不会被改变。
ES6 Module导出
// 输出out.js
var a = 1;
function add(){
a++;
}
export {a, add} // ES6输出
CommonJS引入
var out = require('./out.js'); //ES5输入
console.log('before:', out.a); // before:1
out.add();
console.log('after:', out.a); // after:2
此时,模块的值又再次被改变了。综上四种情况,我们可以得出以下结论:
- CommonJS导出的a值都是不受原有的模块的代码影响的,永远都是1
- 而ES6 Module导出的b值则是随着原有模块的代码影响,执行add()函数之后,变成了2
总结
CommonJS导出的a值是模块里a的拷贝;而ES6 Module导出的a值就是模块里a的引用