ES6模块导出是编译时静态绑定的只读活引用,CommonJS是运行时动态赋值;ES6支持default与named共存,CommonJS仅单出口;ES6循环依赖返回空对象,CommonJS返回执行中快照;ES6顶层this为undefined且强制严格模式,CommonJS中this指向module.exports。

ES6模块导出对象和CommonJS导出对象在行为、机制和使用方式上有本质区别,核心在于:ES6是编译时静态绑定,CommonJS是运行时动态赋值。
导出本质不同
ES6的export不是导出值的拷贝,而是创建对声明的只读绑定;而CommonJS的module.exports导出的是运行时计算出的值的引用或副本。
- ES6中即使导出一个变量,后续修改该变量,导入方看到的仍是最新值(因为是活绑定)
- CommonJS中导出后若重新赋值
module.exports,旧引用不会自动更新;若导出的是对象属性,修改属性值则能被观察到(因共享同一对象)
默认导出(default)与命名导出(named)不可混用
ES6模块中export default和export const x = ...可共存,但CommonJS只有单一出口module.exports,需手动组织结构。
- ES6允许:
export default { a: 1 }; export const b = 2;,导入时可用import obj from 'x'和import { b } from 'x' - CommonJS中写
module.exports = { a: 1 }; exports.b = 2看似类似,实则exports只是module.exports的快捷引用,一旦重写module.exports,exports就失效
循环依赖处理策略不同
ES6模块在解析阶段就建立绑定关系,遇到循环依赖会返回未初始化的空对象({}),待模块执行完再填充;CommonJS则返回当前已执行部分的exports对象。
立即学习“Java免费学习笔记(深入)”;
- ES6中A导入B、B又导入A:A中拿到的是B模块的“占位对象”,B执行完后A才能访问其真实导出内容
- CommonJS中A导入B,B导入A:A中拿到的是B执行到
require那一行时的exports快照,可能不完整
顶层this与严格模式
ES6模块默认启用严格模式,且顶层this为undefined;CommonJS模块中顶层this指向module.exports。
- ES6中
this不能用于挂载导出项,必须显式export - CommonJS中可直接写
this.x = 1等价于module.exports.x = 1(但不推荐,易混淆)










