🗒️module
<script src="a.js"></script> <!-- 引入脚本 -->
<script type="module" src="b.js"></script> <!-- 引入模块 -->默认模式
非严格
严格
top-level
global
module
this
window
undefined
执行
同步
异步
import 声明
不可以
可以
动态 import()
可以
可以
ES6 模块标准有两部分:
声明性语法:用于导入和导出(导入是导出实体的只读视图)
可编程的 loader API:配置加载方式、有条件地加载
模块是单例的,即使一个模块被多次导入,它也只存在一个“实例”。
ES5 模块系统
CommonJS 模块:专为同步加载和服务器而设计,偏好单个导出、支持循环依赖
异步模块定义(AMD,如 RequireJS):专为异步加载和浏览器而设计
ES6 Module
语法比 CommonJS 的更紧凑
可以进行静态分析(用于静态检查、优化等)
对循环依赖的支持比 CommonJS 的要好(虽然支持,但尽量避免如此)
1. export 声明
export 不受 temporal dead zone 规则的约束。
两种类型:
named export:一个 module 可以有多个(多个命名导出,它们以名称区分)
default export:每个 module 只能有一个(单个默认导出,通常是一个 function 或 class)
可以同时使用两者,但通常最好分开使用。
named export
default export
表示在 import 时可以随便起名字。
注意:此时导出的是变量的“值”(和导出变量的行为是不一样的),此时修改变量不会导致其它模块中引入的 default 值发生改变。
re-export 或聚合
2. import 声明
两种方式:
importdeclaration:只能用于 modules 中,且只能在 top-level(不能在 block 或 function 里)dynamic import
import():可用于 non-module contexts
import 声明的四种形式:
named import
default import
namespace import
side effect import
静态 import 声明用来导入 read-only live bindings(只读实时绑定),之所以叫 live bindings,是因为它们的值只能由 export 绑定的模块来更新,而 import 它的模块不能 re-assign。
尽管如此,任何持有导出对象的模块都可以改变该对象,并且所有其它导入相同值的模块都可以观察到修改后的值。还可以通过 module namespace object 来观察新值。
需要注意的是,import 与一般的赋值不同,import 后的变量只是改变了名字,它仍然与原来的变量是同一个,即便变量是非引用型的基本类型。
Last updated