差异主要有如下几点:
- CommonJS 输出是值的拷贝,即原来模块中的值改变不会影响已经加载的该值,ES6静态分析,动态引用,输出的是值的引用,值改变,引用也改变,即原来模块中的值改变则该加载的值也改变。
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
- CommonJS 加载的是整个模块,即将所有的接口全部加载进来,ES6 可以单独加载其中的某个接口(方法),
- CommonJS this 指向当前模块,ES6 this 指向undefined
CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
ES6 模块的运行机制与 CommonJS 不一样。
JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。
等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
ES6 模块不会缓存运行结果,而是动态地去被加载的模块取值,并且变量总是绑定其所在的模块。
下面是一个表格,展示了ES6模块与CommonJS模块之间的差异:
特点 | ES6模块 | CommonJS模块 |
---|---|---|
语法 | 使用import 和export 语法 | 使用require 和module.exports 语法 |
动态导入 | 支持动态导入,可以根据条件导入不同的模块 | 不支持动态导入,导入的模块在脚本加载时确定 |
导入和导出的类型 | 可以导入和导出变量、函数、类、默认导出等多种类型 | 只能导入和导出整个模块对象 |
导入方式 | 可以使用命名导入和默认导入方式 | 只支持命名导入方式 |
导出方式 | 可以使用命名导出和默认导出方式 | 只支持命名导出方式 |
模块加载时机 | 在编译时就会生成所有模块的依赖关系,可以进行静态分析 | 在运行时加载模块,无法进行静态分析 |
模块间的关系 | 每个ES6模块都有自己的作用域,相互之间没有依赖关系 | 模块之间共享相同的作用域,可以直接访问和修改导出的变量和函数 |
浏览器支持 | 部分浏览器原生支持,可以使用Babel转译实现兼容性 | 不支持,需要使用工具如Browserify、Webpack进行转译和打包 |
Node.js使用 | 需要使用--experimental-modules 标志启用ES模块支持 | 原生支持CommonJS模块 |
请注意,这些是一般规则,具体的差异可能因为不同的运行环境和工具而有所不同。
个人笔记记录 2021 ~ 2025