你所不知道的JS模块
发布于 5 年前 作者 yyin 3108 次浏览 来自 分享

大家应该都JS模块化有一定的了解。主流规范有两种:

  • CommonJS
  • ES6 Module

其中,CommonJS是Node.js官方推荐的规范。常见关键字就是requiremodule.exports

而ES6 Module则是ESMAScript官方标准,常见关键字为importexport

日常开发中,这两种规范都可能用上,因此大家有可能会忽略这两种规范之间的细微差异。本文将讲解这两种规范的一个关键差异:值的引用

相同方式

即采用相同的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的引用

1 回复
回到顶部