ES6 模块与 CommonJS 模块的差异

javaScript

import 与 require都是为了解决js模块化而出现的,在es6之前只能用第三方库实现require功能,两者之间主要有以下几点不同。

不同点

1)、ES6 输入的模块变量,只是一个“符号连接”,这个变量是只读的,对它进行重新赋值会报错。。
2)、import只能作为模块顶层的语句出现,不能出现在 function 或者是 if 里面。
3)、不管 import 的语句出现位置在哪儿,在模块初始化的时,所有的 import 都已导入完成(预解析)。
4)、通过 export 接口输出的是同一个值。其他的模块加载得到的都是同样的实例。
5)、按需加载方式不同,CommonJS 通过 require() 函数加载,ES6 通过 import() 函数加载 (支持动态生成路径) ,并且得到一个 promise 对象,支持 Promise.all()、async…await 等语法。
6)、CommonJS 模块输出的是 exports 缓存,ES6 模块是动态引用。
7)、CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

PS

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

ES6 模块的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,不会去执行模块,而是只生成一个引用。等到真的需要用到时,再到模块里面去取值。换句话说,ES6 的import有点像 Unix 系统的“符号连接”,原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。

es6模块在浏览器的引用

<script type="module"> import utils from "./utils.js"; // other code </script>
  • 代码是在模块作用域之中运行,内部的顶层变量外部是不可见。
  • 模块脚本自动采用严格模式,不管有没有声明use strict
  • 模块之中,可以使用import命令加载其他模块(.js后缀不可省略,需要提供绝对 URL 或相对 URL),也可以使用export命令输出对外接口。
  • 模块之中,顶层的this关键字返回undefined,而不是指向window。也就是说,在模块顶层使用this关键字,是无意义的。
  • 同一个模块如果加载多次,将只执行一次(在url参数不变的情况下)。
推荐文章