?uem/p1-90`super,则为语法错误,除非super 的源文本是由super 的其他Script Record 封装有关正在求值的脚本的信息。每个 script record 都
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[Realm]] |
a |
创建此脚本的 realm。 |
| [[ECMAScriptCode]] |
a |
解析此脚本源文本的结果。 |
| [[LoadedModules]] |
a |
从此脚本导入的说明符字符串到已解析 |
| [[HostDefined]] |
anything (default value is |
保留给需要将附加信息与脚本关联的 |
实现可以在对该脚本源文本执行 ParseScript 之前解析脚本源文本,并分析其中的
当为脚本求值建立
调用时,它执行以下步骤:
var 和 function 绑定(由非严格与显式 var 或函数声明不同,直接在
super,则为语法错误。
重复 export default
ModuleRequest Record 表示使用给定导入属性导入模块的请求。它由以下字段组成:
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[Specifier]] | a String | 模块说明符 |
| [[Attributes]] |
a |
导入属性 |
LoadedModuleRequest Record 表示导入模块的请求以及由此得到的
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[Specifier]] | a String | 模块说明符 |
| [[Attributes]] |
a |
导入属性 |
| [[Module]] |
a |
与此模块请求对应的已加载模块 |
ImportAttribute Record 由以下字段组成:
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[Key]] | a String |
|
| [[Value]] | a String | 属性值 |
Module Record 封装有关单个模块的导入和导出的结构信息。这些信息用于链接一组相互连接模块的导入和导出。Module Record
出于规范目的,Module Record 是
Module Record 定义
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[Realm]] |
a |
创建此模块的 |
| [[Environment]] |
a |
|
| [[Namespace]] |
an Object or |
如果已为此模块创建 Module Namespace Object( |
| [[HostDefined]] |
anything (default value is |
保留给需要将附加信息与模块关联的 |
| 方法 | 用途 | 定义 |
|---|---|---|
| LoadRequestedModules ( [ hostDefined ] ) | 抽象方法 LoadRequestedModules,接收可选参数 hostDefined (任意值);返回值:Promise。 它通过递归加载模块的所有依赖项,为模块链接做好准备。 |
在本规范中,它在以下类型中具有定义; |
| GetExportedNames ( [ exportStarSet ] ) | 抽象方法 GetExportedNames,接收可选参数 exportStarSet ( 它返回直接或间接从此模块导出的所有名称的列表。 调用此方法之前, |
在本规范中,它在以下类型中具有定义; |
| ResolveExport ( exportName [ , resolveSet ] ) | 抽象方法 ResolveExport,接收参数 exportName (String)和可选参数 resolveSet ( 它返回由此模块导出的某个名称的绑定。绑定由形式为 { [[Module]]: 每次以特定的 exportName、resolveSet 参数对调用此操作时,它都必须返回相同结果。 调用此方法之前, |
在本规范中,它在以下类型中具有定义; |
| Link ( ) | 抽象方法 Link,接收无参数;返回值:( 它通过传递地解析所有模块依赖项并创建 调用此方法之前, |
在本规范中,它在以下类型中具有定义; |
| Evaluate ( ) | 抽象方法 Evaluate,接收无参数;返回值:Promise。 它返回一个用于此模块及其依赖项求值的 promise;如果求值成功或此前已经成功求值,则该 promise 会兑现;如果发生求值错误或此前已经求值失败,则会拒绝。如果 promise 被拒绝, 调用此方法之前, |
在本规范中,它在以下类型中具有定义; |
Cyclic Module Record 用于表示有关模块的信息,该模块可以与
除
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[Status]] |
|
初始为 |
| [[EvaluationError]] |
a throw completion or |
表示求值期间发生异常的抛出完成。如果未发生异常,或者 [[Status]] 不是 |
| [[DFSAncestorIndex]] |
an integer or |
仅在 |
| [[RequestedModules]] |
a |
与此模块中的导入关联的 |
| [[LoadedModules]] |
a |
从此 record 所表示模块用于请求导入模块的说明符字符串及相应导入属性,到已解析 |
| [[CycleRoot]] |
a |
循环中第一个被访问的模块,即强连通分量的根 DFS 祖先。对于不在循环中的模块,这就是模块自身。 |
| [[HasTLA]] | a Boolean |
此模块自身是否为异步模块(例如,它是 |
| [[AsyncEvaluationOrder]] |
|
此字段最初设置为 |
| [[TopLevelCapability]] |
a |
如果此模块是某个循环的 [[CycleRoot]],并且对该循环中的某个模块调用了 |
| [[AsyncParentModules]] |
a |
如果此模块或某个依赖项的 [[HasTLA]] 为 |
| [[PendingAsyncDependencies]] |
an integer or |
如果此模块具有任何异步依赖项,则此字段跟踪该模块尚待执行的异步依赖模块数量。当该字段达到 0 且不存在执行错误时,具有异步依赖项的模块将被执行。 |
除
| 方法 | 用途 | 定义 |
|---|---|---|
| InitializeEnvironment ( ) | 抽象方法 InitializeEnvironment,接收无参数;返回值:( |
在本规范中,它在以下类型中具有定义; |
| ExecuteModule ( [ capability ] ) | 抽象方法 ExecuteModule,接收可选参数 capability ( |
在本规范中,它在以下类型中具有定义; |
GraphLoadingState Record 是
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[PromiseCapability]] |
a |
加载过程完成时要兑现的 promise。 |
| [[IsLoading]] | a Boolean | 如果加载过程尚未完成,无论是成功还是出错,则为 true。 |
| [[PendingModulesCount]] | a non-negative integer |
它跟踪待处理的 |
| [[Visited]] |
a |
它是当前加载过程中已经加载的 |
| [[HostDefined]] |
anything (default value is |
它 |
以下是
a
<link rel="preload" as="..."> 标签设置正确的 fetch destination。
import() 表达式绝不会设置 hostDefined 参数。
a
a
当 InnerModuleEvaluation 正在遍历模块时,该模块处于
当异步循环中的模块不处于
当根 module 的异步执行兑现时,此函数确定可在该完成时一起同步执行的模块列表,并将它们填充到 execList 中。
本非规范性章节给出几个常见模块图的链接和求值示例,重点说明错误可能如何发生。
首先考虑以下简单模块图:
首先假设不存在错误条件。当
接下来考虑在成功调用 A.
最后,考虑在成功调用
现在考虑另一种错误条件:
在这种场景中,模块 A 声明对另一个模块的依赖,但该模块不存在
这里加载、链接和求值错误之间的差异源于以下特性:
现在,考虑具有循环的模块图:
这里假设入口点是模块 A,因此
随后,
在成功情况下,循环模块图的求值阶段会发生类似的过程。
现在考虑 A 存在链接错误的情况;例如,它试图从 C 导入一个不存在的绑定。在这种情况下,上述步骤仍然会发生,包括第二次对 A 调用
或者,考虑 A 存在求值错误的情况;例如,其源代码抛出异常。在这种情况下,与上述步骤对应的求值阶段仍然会发生,包括第二次对 A 调用 await 或依赖顶层 await 的模块,还会通过 [[AsyncParentModules]] 以及
最后,考虑一个具有循环、且所有模块都异步完成的模块图:
加载和链接与之前一样发生,最终所有模块的 [[Status]] 都设置为
调用 A.
|
字段
|
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 完成执行(因为它是唯一仍在执行的模块)。发生这种情况时,再次调用 await,则可能与 B 并行执行)。更新后的模块字段如
|
字段
|
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 |
|---|---|
| [[DFSAncestorIndex]] | 0 |
| [[Status]] | |
| [[AsyncEvaluationOrder]] | |
| [[AsyncParentModules]] | « » |
| [[PendingAsyncDependencies]] | 0 |
或者,考虑失败情况:C 执行失败,并在 B 完成执行之前返回错误。发生这种情况时,会调用
|
字段
|
A | C |
|---|---|---|
| [[DFSAncestorIndex]] | 0 | 0 |
| [[Status]] | ||
| [[AsyncEvaluationOrder]] | ||
| [[AsyncParentModules]] | « » | « A » |
| [[PendingAsyncDependencies]] | 1 (B) | 0 |
| [[EvaluationError]] | C 的求值错误 |
A 将以与 C 相同的错误被拒绝,因为 C 会以 C 的错误对 A 调用
|
字段
|
A |
|---|---|
| [[DFSAncestorIndex]] | 0 |
| [[Status]] | |
| [[AsyncEvaluationOrder]] | |
| [[AsyncParentModules]] | « » |
| [[PendingAsyncDependencies]] | 0 |
| [[EvaluationError]] | C 的求值错误 |
然后,B 在没有错误的情况下完成执行。发生这种情况时,再次调用
|
字段
|
A | B |
|---|---|---|
| [[DFSAncestorIndex]] | 0 | 0 |
| [[Status]] | ||
| [[AsyncEvaluationOrder]] | 4 | 1 |
| [[AsyncParentModules]] | « » | « A » |
| [[PendingAsyncDependencies]] | 0 | 0 |
| [[EvaluationError]] | C 的求值错误 |
Source Text Module Record 用于表示有关模块的信息,该模块由使用
除
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[ECMAScriptCode]] | a Parse Node |
使用 |
| [[Context]] |
an |
与此模块关联的 |
| [[ImportMeta]] |
an Object or |
通过 import.meta 元属性暴露的对象。在 ECMAScript 代码访问它之前,它为 |
| [[ImportEntries]] |
a |
从此 |
| [[LocalExportEntries]] |
a |
从此 |
| [[IndirectExportEntries]] |
a |
从此export * as namespace 声明的导出。
|
| [[StarExportEntries]] |
a |
从此export * 声明,但不包括 export * as namespace 声明。
|
ImportEntry Record 是归纳单个声明式导入相关信息的
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[ModuleRequest]] |
a |
表示 |
| [[ImportName]] |
a String or |
由 [[ModuleRequest]] 标识的模块导出所需绑定时使用的名称。值 |
| [[LocalName]] | a 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";
|
不创建 |
||
ExportEntry Record 是归纳单个声明式导出相关信息的
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[ExportName]] |
a String or |
此模块用于导出该绑定的名称。 |
| [[ModuleRequest]] |
a |
表示 |
| [[ImportName]] |
a String, |
由 [[ModuleRequest]] 标识的模块导出所需绑定时使用的名称。如果 export * as ns from "mod" 声明。export * from "mod" 声明。
|
| [[LocalName]] |
a String or |
在导入模块内部用于局部访问所导出值的名称。如果无法从模块内部局部访问导出的值,则为 |
| 导出语句形式 | [[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";
|
|
|
|
|
以下定义规定
export * from 以同一名称两次导出同一绑定或命名空间所产生的冲突就可以被忽略,而不是在 await。实现可以在对该模块源文本执行 ParseModule 之前解析模块源文本,并分析其中的
以下是
a
a
如果找到定义模块,则返回
调用时执行以下步骤:
* 导出以下是
a
a
Synthetic Module Record 用于表示由规范定义的模块相关信息。其导出名称在创建时静态定义,而对应值可以随时间通过
除
| 字段名称 | 值类型 | 含义 |
|---|---|---|
| [[ExportNames]] | a |
模块的导出名称。此列表不 |
| [[EvaluationSteps]] | an |
对模块求值时要执行的初始化逻辑,以 |
以下是
a
a
a
a
a
宿主定义的抽象操作 HostLoadImportedModule,接收参数 referrer ((
HostLoadImportedModule 的实现必须符合以下要求:
如果以两个 (referrer, moduleRequest) 对多次调用此操作,并且满足:
并且它执行
如果 moduleRequest.[[Attributes]] 中存在条目 entry,使得 entry.[[Key]] 是
实际执行的过程由
宿主定义的抽象操作 HostGetSupportedImportAttributes,接收无参数;返回值:
HostGetSupportedImportAttributes 的实现必须符合以下要求:
HostGetSupportedImportAttributes 的默认实现是返回新的空
GetModuleNamespace 永远不会抛出异常。相反,无法解析的名称此时会直接从命名空间中排除。除非它们全都是未在任何地方被显式请求的歧义星号导出,否则它们之后会导致真正的链接错误。
上述规则意味着,
ExportedBindings 是与
它按以下产生式分别定义:
ExportedNames 是
它按以下产生式分别定义:
本规范使用