?
u
m
/
p
1-9
0
`
super
为 super
的源文本为正通过直接 eval 处理的 eval 代码),则为语法错误。直接 eval 中 super
的额外The syntax-directed operation
脚本记录封装了正被求值的脚本的信息。每个
字段名 | 值类型 | 含义 |
---|---|---|
[[Realm]] |
一个 |
此脚本被创建时所在的领域。 |
[[ECMAScriptCode]] |
一个 |
解析此脚本源文本的结果。 |
[[LoadedModules]] |
|
从此脚本导入的说明符字符串到已解析的 |
[[HostDefined]] |
任意类型(默认值为 |
为需要将额外信息与脚本关联的 |
The abstract operation ParseScript takes arguments sourceText (ECMAScript 源文本), realm (一个
实现可以在对该脚本源文本求值 ParseScript 之前解析脚本源文本并分析早期错误条件。然而,任何错误的报告必须推迟到本规范实际对该源文本执行 ParseScript 的时候。
The abstract operation ScriptEvaluation takes argument scriptRecord (一个 Script
The abstract operation GlobalDeclarationInstantiation takes arguments script (一个
当为求值脚本建立执行上下文时,声明在当前全局环境中实例化。代码中声明的每个全局绑定都被实例化。
被调用时执行以下步骤:
var
和 function
绑定(除了由非严格直接 eval 引入的那些)是不可配置的,因此是受限的全局属性。与显式的 var 或 function 声明不同,直接在全局对象上创建的属性会产生可能被 let/const/class 声明遮蔽的全局绑定。
super
,则为语法错误。
重复 ExportedNames 规则意味着在 export default
The abstract operation
ModuleRequest Record 表示使用给定导入属性导入模块的请求。它由以下字段组成:
字段名 | 值类型 | 含义 |
---|---|---|
[[Specifier]] | 字符串 | 模块说明符 |
[[Attributes]] |
|
导入属性 |
LoadedModuleRequest Record 表示导入模块的请求以及生成的
字段名 | 值类型 | 含义 |
---|---|---|
[[Specifier]] | 字符串 | 模块说明符 |
[[Attributes]] |
|
导入属性 |
[[Module]] |
|
对应此模块请求的已加载模块 |
ImportAttribute Record 由以下字段组成:
字段名 | 值类型 | 含义 |
---|---|---|
[[Key]] | 字符串 |
|
[[Value]] | 字符串 | 属性值 |
The abstract operation ModuleRequestsEqual takes arguments left (
The syntax-directed operation
Module Record 封装了关于单个模块导入和导出的结构信息。这些信息用于链接连接模块集合的导入和导出。Module Record 包含四个仅在求值模块时使用的字段。
出于规范目的,Module Record 值是
Module Record 定义了
字段名 | 值类型 | 含义 |
---|---|---|
[[Realm]] |
|
创建此模块的领域。 |
[[Environment]] |
|
包含此模块顶级绑定的 |
[[Namespace]] |
Object 或 |
Module Namespace Object( |
[[HostDefined]] |
任意类型(默认值为 |
为需要将附加信息与模块关联的 |
方法 | 目的 |
---|---|
LoadRequestedModules([hostDefined]) |
通过递归加载所有依赖项来准备模块以进行链接,并返回一个 promise。 |
GetExportedNames([exportStarSet]) |
返回从此模块直接或间接导出的所有名称的列表。 在调用此方法之前,LoadRequestedModules 必须已成功完成。 |
ResolveExport(exportName [, resolveSet]) |
返回此模块导出的名称的绑定。绑定由 ResolvedBinding Record 表示,形式为 { [[Module]]: 每次使用特定 exportName、resolveSet 对作为参数调用此操作时,必须返回相同结果。 在调用此方法之前,LoadRequestedModules 必须已成功完成。 |
Link() |
通过传递性地解析所有模块依赖项并创建 在调用此方法之前,LoadRequestedModules 必须已成功完成。 |
Evaluate() |
返回此模块及其依赖项求值的 promise,在成功求值或已成功求值时解决,在求值错误或已求值失败时拒绝。如果 promise 被拒绝,期望 在调用此方法之前,Link 必须已成功完成。 |
The abstract operation EvaluateModuleSync takes argument module (
Cyclic Module Record(循环模块记录) 用于表示一个模块与其它同属 Cyclic
除
字段名 (Field Name) | 值类型 (Value Type) | 含义 (Meaning) |
---|---|---|
[[Status]] |
|
初始为 |
[[EvaluationError]] |
throw completion 或 |
表示求值期间发生的异常的 throw completion。若无异常或 [[Status]] 不是 |
[[DFSAncestorIndex]] |
整数或 |
仅在 Link 与 Evaluate 过程中使用的辅助字段。若 [[Status]] 为 |
[[RequestedModules]] |
|
与该模块中的 import 相关联的 |
[[LoadedModules]] |
|
将此记录所代表模块使用的说明符字符串(及相对导入属性)映射到解析得到的 |
[[CycleRoot]] |
Cyclic |
环的首个访问模块,即强连通分量(SCC)的深度优先根祖先。对不在环中的模块,该字段为其自身。Evaluate 完成后,模块的 [[DFSAncestorIndex]] 等于其 [[CycleRoot]] 的深度优先遍历索引。 |
[[HasTLA]] | Boolean |
该模块自身是否为异步(例如包含顶层 await 的 Source Text |
[[AsyncEvaluationOrder]] |
|
初始为 |
[[TopLevelCapability]] |
|
若此模块是某个环的 [[CycleRoot]] 且对该环中某模块调用了 Evaluate(),此字段保存该整体求值的 PromiseCapability,用于完成 Evaluate() 返回的 Promise。除非对依赖发起顶层 Evaluate(),否则依赖的该字段为 |
[[AsyncParentModules]] |
Cyclic |
若此模块或其依赖具有 [[HasTLA]] |
[[PendingAsyncDependencies]] |
整数或 |
若该模块有异步依赖,此值跟踪剩余尚未执行完成的异步依赖模块数量。计数降至 0 且无执行错误时,该模块执行。 |
除
方法 (Method) | 目的 (Purpose) |
---|---|
InitializeEnvironment() |
初始化模块的 |
ExecuteModule([promiseCapability]) |
在其执行上下文内求值模块代码。若模块 [[HasTLA]] 为 |
GraphLoadingState Record(图加载状态记录) 是包含模块图加载流程信息的记录,用于在
字段名 (Field Name) | 值类型 (Value Type) | 含义 (Meaning) |
---|---|---|
[[PromiseCapability]] |
|
加载流程完成时要 resolve 的 promise。 |
[[IsLoading]] | Boolean |
若加载流程尚未成功或失败完成则为 |
[[PendingModulesCount]] | 非负整数 |
跟踪未完成 |
[[Visited]] |
Cyclic |
已在本次加载过程中加载的循环模块集合,用于避免循环依赖无限循环。 |
[[HostDefined]] |
任意(默认 |
自 |
以下为循环模块记录对
The LoadRequestedModules concrete method of Cyclic
<link rel="preload" as="...">
设置正确的 fetch destination。import()
表达式不会设置该参数。
The abstract operation InnerModuleLoading takes arguments state (GraphLoadingState
The abstract operation ContinueModuleLoading takes arguments state (GraphLoadingState
The Link concrete method of Cyclic
The abstract operation InnerModuleLinking takes arguments module (
The Evaluate concrete method of Cyclic
The abstract operation InnerModuleEvaluation takes arguments module (
模块在 InnerModuleEvaluation 遍历时为
依赖某异步环的模块在该环不处于
The abstract operation ExecuteAsyncModule takes argument module (Cyclic
The abstract operation GatherAvailableAncestors takes arguments module (Cyclic
当根 module 的异步执行 fulfilled 时,此函数确定可同步继续执行的模块集合,填入 execList。
The abstract operation AsyncModuleExecutionFulfilled takes argument module (Cyclic
The abstract operation AsyncModuleExecutionRejected takes arguments module (Cyclic
本非规范性章节展示若干常见模块图的链接与求值示例,重点说明错误如何出现。
先看一个简单模块图:
假设无错误:
若在成功的 A.LoadRequestedModules() 之后出现链接错误:例如
若在成功 Link() 后出现求值错误:例如 C 求值成功但 B 中代码抛出异常,则 A.Evaluate() 返回被拒绝的 Promise;异常记录在 A 与 B 的 [[EvaluationError]],二者变为
接着看一个无法解析模块的情形:
此时 A 依赖的模块不存在(
加载、链接与求值错误的差异:
现在看一个包含环的模块图:
以 A 为入口,LoadRequestedModules 触发对 B 与 C 的加载;因循环再次访问 A 时不再重复。成功后所有模块状态同时从
随后 Link 通过 DFS 对环进行
若 A 存在链接错误(如从 C 导入不存在的绑定),第二次回到 A 时提前返回,但最终在 InitializeEnvironment(调用 C.ResolveExport 后)抛出
若 A 存在求值错误(源码抛异常),则求值阶段对应逻辑使 A 与仍
最后看一个所有模块异步完成的循环图:
加载与链接后全部为
调用 A.Evaluate():A、B、D 设为
字段 / 模块
|
A | B | C | D | E |
---|---|---|---|---|---|
[[DFSAncestorIndex]] | 0 | 0 | 0 | 0 | 4 |
[[Status]] | |||||
[[AsyncEvaluationOrder]] | 4 | 1 | 3 | 0 | 2 |
[[AsyncParentModules]] | « » | « A » | « A » | « B, C » | « C » |
[[PendingAsyncDependencies]] | 2 (B, C) | 1 (D) | 2 (D, E) | 0 | 0 |
假设 E 先完成,调用
字段
|
C | E |
---|---|---|
[[DFSAncestorIndex]] | 0 | 4 |
[[Status]] | ||
[[AsyncEvaluationOrder]] | 3 | |
[[AsyncParentModules]] | « A » | « C » |
[[PendingAsyncDependencies]] | 1 (D) | 0 |
接着 D 完成:D 设为
字段
|
B | C | D |
---|---|---|---|
[[DFSAncestorIndex]] | 0 | 0 | 0 |
[[Status]] | |||
[[AsyncEvaluationOrder]] | 1 | 3 | |
[[AsyncParentModules]] | « A » | « A » | « B, C » |
[[PendingAsyncDependencies]] | 0 | 0 | 0 |
然后 C 完成:设为
字段
|
A | C |
---|---|---|
[[DFSAncestorIndex]] | 0 | 0 |
[[Status]] | ||
[[AsyncEvaluationOrder]] | 4 | |
[[AsyncParentModules]] | « » | « A » |
[[PendingAsyncDependencies]] | 1 (B) | 0 |
随后 B 完成:设为
字段
|
A | B |
---|---|---|
[[DFSAncestorIndex]] | 0 | 0 |
[[Status]] | ||
[[AsyncEvaluationOrder]] | 4 | |
[[AsyncParentModules]] | « » | « A » |
[[PendingAsyncDependencies]] | 0 | 0 |
最终 A 完成:A 设为
字段
|
A |
---|---|
[[DFSAncestorIndex]] | 0 |
[[Status]] | |
[[AsyncEvaluationOrder]] | |
[[AsyncParentModules]] | « » |
[[PendingAsyncDependencies]] | 0 |
若失败:假设 C 先执行出错,在
字段
|
A | C |
---|---|---|
[[DFSAncestorIndex]] | 0 | 0 |
[[Status]] | ||
[[AsyncEvaluationOrder]] | ||
[[AsyncParentModules]] | « » | « A » |
[[PendingAsyncDependencies]] | 1 (B) | 0 |
[[EvaluationError]] | C 的求值错误 |
A 也被拒绝并记录相同错误;见
字段
|
A |
---|---|
[[DFSAncestorIndex]] | 0 |
[[Status]] | |
[[AsyncEvaluationOrder]] | |
[[AsyncParentModules]] | « » |
[[PendingAsyncDependencies]] | 0 |
[[EvaluationError]] | C 的 Evaluation Error |
若随后 B
字段
|
A | B |
---|---|---|
[[DFSAncestorIndex]] | 0 | 0 |
[[Status]] | ||
[[AsyncEvaluationOrder]] | 4 | 1 |
[[AsyncParentModules]] | « » | « A » |
[[PendingAsyncDependencies]] | 0 | 0 |
[[EvaluationError]] | C 的 Evaluation Error |
Source Text Module Record(源码文本模块记录) 表示由 ECMAScript 源文本(
该记录可与其它
除
字段名 | 值类型 | 含义 |
---|---|---|
[[ECMAScriptCode]] | Parse Node |
以 |
[[Context]] |
|
与模块关联的执行上下文;在环境初始化前为 |
[[ImportMeta]] |
Object 或 |
通过 import.meta 暴露的对象;首次访问前为 |
[[ImportEntries]] |
ImportEntry |
源码导入语句解析出的 ImportEntry 列表。 |
[[LocalExportEntries]] |
ExportEntry |
对应模块内部声明的导出。 |
[[IndirectExportEntries]] |
ExportEntry |
对应重导出的导入或 export * as namespace 的导出。
|
[[StarExportEntries]] |
ExportEntry |
对应 export * (不含 export * as namespace )的导出。
|
ImportEntry Record(导入项记录) 汇总单个声明式导入的信息,其字段见
字段名 | 值类型 | 含义 |
---|---|---|
[[ModuleRequest]] |
|
表示 |
[[ImportName]] |
String 或 |
目标模块中导出的绑定名称。 |
[[LocalName]] | String | 在本模块中访问该导入值的局部名字。 |
导入语句形式 | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] |
---|---|---|---|
import v from "mod";
|
|
|
|
import * as ns from "mod";
|
|
|
|
import {x} from "mod";
|
|
|
|
import {x as v} from "mod";
|
|
|
|
import "mod";
|
不创建 ImportEntry |
ExportEntry Record(导出项记录) 汇总单个声明式导出信息,字段见
字段名 | 值类型 | 含义 |
---|---|---|
[[ExportName]] |
String 或 |
对外导出的名称。 |
[[ModuleRequest]] |
|
表示 |
[[ImportName]] |
String、 |
从 [[ModuleRequest]] 指定模块导出的绑定名;export * as ns 用 export * 用 |
[[LocalName]] |
String 或 |
在本模块内部访问该导出值的名字;若非本地可访问则为 |
导出语句形式 | [[ExportName]] | [[ModuleRequest]] | [[ImportName]] | [[LocalName]] |
---|---|---|---|---|
export var v;
|
|
|
|
|
export default function f() {}
|
|
|
|
|
export default function () {}
|
|
|
|
|
export default 42;
|
|
|
|
|
export {x};
|
|
|
|
|
export {v as x};
|
|
|
|
|
export {x} from "mod";
|
|
|
|
|
export {v as x} from "mod";
|
|
|
|
|
export * from "mod";
|
|
|
|
|
export * as ns from "mod";
|
|
|
|
|
以下定义 Source Text
The abstract operation ParseModule takes arguments sourceText (ECMAScript 源文本), realm (
await
。实现可提前解析并检查早期错误,但错误报告需延迟到实际调用 ParseModule 时。
以下为 Source Text
The GetExportedNames concrete method of Source Text
export *
循环起点。GetExportedNames 不过滤或抛出模糊的星号再导出绑定。
The ResolveExport concrete method of Source Text
尝试解析导出名称到定义的模块与局部绑定名。若是命名空间导出且无本地绑定,则 [[BindingName]] 为
It performs the following steps when called:
export * from
提供)以下为 Source Text
The InitializeEnvironment concrete method of Source Text
The ExecuteModule concrete method of Source Text
Synthetic Module Record(合成模块记录) 表示由规范定义的模块,其导出名称在创建时静态确定,但值可通过
除
字段名 | 值类型 | 含义 |
---|---|---|
[[ExportNames]] | 字符串列表 | 模块的导出名称;无重复。 |
[[EvaluationSteps]] | 抽象闭包 | 求值期间的初始化逻辑,以模块自身为唯一参数;不得修改 [[ExportNames]];可返回突然完成。 |
The abstract operation CreateDefaultExportSyntheticModule takes argument defaultExport (
The abstract operation ParseJSONModule takes argument source (String) and returns
The abstract operation SetSyntheticModuleExport takes arguments module (Synthetic
以下为合成模块记录对
The LoadRequestedModules concrete method of Synthetic
The GetExportedNames concrete method of Synthetic
The ResolveExport concrete method of Synthetic
The Link concrete method of Synthetic
The Evaluate concrete method of Synthetic
The abstract operation GetImportedModule takes arguments referrer (Cyclic
The host-defined abstract operation HostLoadImportedModule takes arguments referrer (Script
在浏览器中,用户点击:
<button type="button" onclick="import('./foo.mjs')">Click me</button>
执行 import()
时可能没有活动脚本或模块(执行上下文栈顶 ScriptOrModule 为
HostLoadImportedModule 的实现需满足:
若多次以相同 referrer 且
若 moduleRequest.[[Attributes]] 存在键
实际过程由
The abstract operation FinishLoadingImportedModule takes arguments referrer (一个 Script
The abstract operation AllImportAttributesSupported takes argument attributes (
The host-defined abstract operation HostGetSupportedImportAttributes takes no arguments and returns 字符串列表. 允许
HostGetSupportedImportAttributes 的实现必须符合以下要求:
默认实现返回一个新的空列表。
The abstract operation GetModuleNamespace takes argument module (
GetModuleNamespace 不会抛出异常。不可解析的名称此时直接排除;除非它们全是未被显式请求的歧义星号导出,否则稍后会导致真实的链接错误。
The syntax-directed operation
The syntax-directed operation
The syntax-directed operation
上述规则意味着
The syntax-directed operation
ExportedBindings 是一个
It is defined piecewise over the following productions:
The syntax-directed operation
ExportedNames 是
It is defined piecewise over the following productions:
The syntax-directed operation
The syntax-directed operation
The syntax-directed operation