面试题
CommonJS 和 ES6模块的区别是什么?

CommonJS 和 ES6模块的区别是什么?

  • Node.js 的模块系统采用 CommonJS 规范,它并不是 JavaScript 语言规范的正式组成部分。 使用require()加载和module.exports输出,代码运行阶段同步加载JS文件。
  • 前端的模块系统则采用ES6模块规范,这是 JavaScript 语言规范的正式组成部分。使用import加载和export输出, 在静态解析阶段分析依赖关系,输出符号引用。ES6模块JS文件相当于自带defer属性,异步加载JS文件,不阻塞DOM构建。

不同点:

  • ES6输入的模块变量是一个引用,变量是只读的,对它进行重新赋值会报错。
  • CommonJS输入的模块变量是一个浅拷贝,如果访问原模块内的实时数据,通过函数返回内部值仍然是可以的。。

共同点是

  • 无论在前端还是在后端,ES6规范和CommonJS也是可以在一个项目中同时使用,甚至相互混用。
  • 二者对于同一模块多次加载都只会执行一次模块内代码,即首次加载执行,后面加载模块不执行其内部代码。

因此export命令后面只能跟着声明式语句,而不能跟表达式(如变量名,字面量)。因为变量只有在声明时,才会产生一个变量引用的符号。

另外,ES6模块的export 不是一个对象简写形式,更不是一个对象,而是export 语法组成部分,用作收集符号用。

另外,CommonJS的module.exports不是模块内部的变量,而是外部传入模块的变量,所以一旦模块内部代码对于exports变量做了修改,其实就是对于外部该变量做了修改, 因此模块代码未执行完,模块的输出module.exports也是有值的,因为这是外部值。