es6模块顶层this指向undefined,commonjs中指向module.exports;前者默认严格模式、禁止隐式全局绑定,后者允许直接赋值导出。

ES6 模块中顶层 this 指向 undefined,而 CommonJS 中顶层 this 指向 module.exports 对象。
ES6 模块:顶层 this 是 undefined
ES6 模块默认处于严格模式,顶层作用域中的 this 不绑定任何对象,直接为 undefined。这是语言规范明确规定的,不能被修改或绕过。
- 试图在模块顶层使用 this(如
this.x = 1)会静默失败或报错(取决于运行环境是否启用严格模式) - 导出必须显式通过
export或export default声明,不能依赖 this 绑定 - 即使在 Node.js 的
.mjs文件或package.json中设"type": "module",该规则依然生效
CommonJS:顶层 this 指向 module.exports
在 CommonJS 模块(如 .cjs 或传统 .js 文件配合 require)中,顶层的 this 是 module.exports 的别名,可直接赋值属性。
-
this.name = 'John'等价于module.exports.name = 'John' - 这种写法虽不推荐(易与普通对象混淆),但在 Node.js 中完全合法且有效
- 注意:
exports是module.exports的引用,但 this 不等于exports,而是等于module.exports
为什么这个区别重要
它反映了两种模块系统的设计哲学差异:
- ES6 模块强调静态性、确定性和隔离性——顶层没有隐式上下文,所有导出都需显式声明
- CommonJS 更偏向动态脚本风格,允许在模块顶层像操作普通对象一样操作 this
- 混用时容易踩坑:比如把 CommonJS 风格的
this.xxx = yyy写进 ES 模块,结果什么也没导出
实际验证小技巧
可在文件顶部加一行快速验证:
- ES 模块中:
console.log(this === undefined) // true - CommonJS 中:
console.log(this === module.exports) // true











