CommonJS与ES6模块的区别

248 阅读2分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

CommonJS模块输出的是一个值的浅拷贝

CommonJs模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化不会影响到这个值。

// common.js
var count = 1;

var printCount = () =>{ 
   return ++count;
}

module.exports = {
     printCount: printCount,
     count: count
};
 // index.js
let v = require('./common');
console.log(v.count); // 1
console.log(v.printCount()); // 2
console.log(v.count); // 1

你可以看到common.js里面改变了count,但是输出的结果还是原来的。这是因为count是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动的值。将common.js里面的module.exports 改写成

module.exports = {
     printCount: printCount,
     get count(){
         return count
     }
};
//这样子的输出结果是 1,2,2

ES6 模块输出的是值的引用

而在ES6当中,写法是这样的,是利用export和import导入的。

// es6.js
export let count = 1;
export function printCount() {
     ++count;
}
// main1.js
import  { count, printCount } from './es6';
console.log(count)
console.log(printCount());
console.log(count)
//这里输出的是1,2,2

ES6模块是动态引用,并且不会缓存,模块里面的便令绑定其所在的模块,而是动态地去加载值,并且不能重新复制。 还有在ES6中export default:

let count = 1;
 function printCount() {
     ++count;
} 
export default { count, printCount}
// main3.js
import res form './main3.js'
console.log(res.count)

总结

CommonJS 模块输出的是一个值的浅拷贝,ES6 模块输出的是值的引用。

CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。

CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段。