如图 5 所示,模块 A 依赖模块 B,模块 B 又依赖模块 A,模块 A 和 B 分别被 require 语句从上往下分为 2 段,记为 A1、A2、B1、B2 。
文章插图
如图 6 所示,代码块的执行顺序为:A1 -> B1 -> B2 -> A2 。
文章插图
使用不当的问题如果 B2 使用了 A2 导出的变量会怎么样呢?模块 A 的模块对象上不存在该变量对应的属性,获取的值为 undefined 。获得 undefined 虽然不符合预期,但一般不会造成 JS 错误 。
可以看到,由于 require 语句直接分割了执行的代码块,CommonJS 模块的导入导出语句的位置会影响模块代码语句的执行结果 。
ES6 模块ES6 模块[4]借助 JS 引擎实现 。JS 引擎实现了 ES6 模块的底层核心逻辑,JS 运行时需要在上层做适配 。适配工作量还不小,比如实现文件的加载,具体可以看一下我发起的一个讨论[5] 。
模块使用报错ES6 模块使用不当时,由 JS 引擎或 JS 运行时的适配层抛出错误 。比如:
// Node.js 中报错 internal/process/esm_loader.js:74 internalBinding('errors').triggerUncaughtException ^ Error [ERR_MODULE_NOT_FOUND]: Cannot find module // 浏览器中报错 Uncaught SyntaxError: The requested module './child.js' does not provide an export named 'b'第一个是 Node.js 适配层触发的内部错误(不是通过 throw 抛出的),第二个是浏览器抛出的 JS 引擎级别的语法错误 。
模块执行顺序ES6 模块有 5 种状态,分别为 unlinked、linking、linked、evaluating 和 evaluated,用循环模块记录(Module Environment Records)[6]的 Status 字段表示 。ES6 模块的处理包括连接(link)和评估(evaluate)两步 。连接成功之后才能进行评估 。
连接主要由函数 InnerModuleLinking[7] 实现 。函数 InnerModuleLinking 会调用函数 InitializeEnvironment[8],该函数会初始化模块的环境记录(Environment Records)[9],主要包括创建模块的执行上下文(Execution Contexts)[10]、给导入模块变量创建绑定[11]并初始化[12]为子模块的对应变量,给 var 变量创建绑定并初始化为 undefined、给函数声明变量创建绑定并初始化为函数体的实例化[13]值、给其他变量创建绑定但不进行初始化 。
对于图 3 的模块关系,连接过程如图 7 所示 。连接阶段采用深度优先遍历,通过函数 HostResolveImportedModule[14] 获取子模块 。完成核心操作的函数 InitializeEnvironment 是后置执行的,所以从效果上看,子模块先于父模块被初始化 。
文章插图
评估主要由函数 InnerModuleEvaluation[15] 实现 。函数 InnerModuleEvaluation 会调用函数 ExecuteModule[16],该函数会评估模块代码(evaluating module.[[ECMAScriptCode]]) 。ES6 规范并没有明确说明这里的评估模块代码具体指什么 。我把 ES6 规范的相关部分反复看了至少十余遍,才得出一个比较合理的解释 。这里的评估模块代码应该指根据代码语句顺序执行条款 13[17]、条款 14[18] 和 条款 15[19] 内的对应小节的“运行时语义:评估(Runtime Semantics: Evaluation)” 。ScriptEvaluation[20] 中的评估脚本(evaluating scriptBody)应该也是这个意思 。可以看到,ES6 规范虽然做了很多设计并且逻辑清晰和自洽,但仍有一些模棱两可的地方,没有达到一种绝对完善和无懈可击的状态 。
对于图 3 的模块关系,评估过程如图 8 所示 。和连接阶段类似,评估阶段也采用深度优先遍历,通过函数 HostResolveImportedModule 获取子模块 。完成核心操作的函数 ExecuteModule 是后置执行的,所以从效果上看,子模块先于父模块被执行 。
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:- 怎么发面好 怎样发面,如何发好面
- 现在网络上流行什么词
- 70年代的缝纫机现在值多少钱 70年代缝纫机回收价格
- “哭晕在厕所”这个网络用语怎么来的?是什么意思
- 再开个店都绰绰有余 女子十年在美发店消费150万
- 你支持现在的网络用语吗?各种缩写,谐音相继面世是好是坏?
- 刘德华锻炼腹肌 每天有适量运动
- 女性在家徒手训练打造翘臀
- 苹果在生活中的妙用
- 某年墨西哥等国出现了流感疫情,引发全球关注.在协助墨西哥等国家防控疫情传播过程中发挥重要作用的国际