ES module 工作原理浅谈

ES module(ECMAScript module)的工作过程涉及三个主要步骤:获取、解析和实例化。

获取步骤涉及获取所有需要的模块。当JavaScript引擎遇到import语句时,它首先查看module map是否已经有了一个与URL匹配的条目。如果没有,则会生成一个新的请求获取这个模块。

然后,JavaScript引擎解析获取到的文件,以便了解其中的模块结构。所有的模块都是在相当于文件顶部使用了严格模式下被解析的。一旦module record创建完成,它就会被放到module map里面去。

最后的步骤是实例化,JavaScript引擎生成一个模块环境记录,它管理module record的变量,然后把内存里的所有导出的变量链接起来。实例化模块图(module graph),JS引擎会使用一个深度优先后序遍历的操作。这意味着在实例化阶段,它会首先设置所有没有依赖的模块的导出,然后再设置这些模块的导入。

值得注意的是,ES module使用的是实时绑定,也就是说,导出模块和导入模块都指向同一片内存地址。如果导出模块修改了一个值,那么这个修改也会在导入模块里体现出来。

例如:
// counter.mjs
console.log('counter module evaluation');
let i = 0;
export function increment() {
  i++;
}
export function get() {
  return i;
}

// main.mjs
import * as counter from './counter.mjs';
console.log('main module evaluation');
counter.increment();
console.log(counter.get());   // 1

在上述例子中,main模块导入了counter模块,并调用其导出的increment函数增加i的值。然后,通过调用get函数,我们可以看到,导出模块的i值的变化在导入模块里也得到了体现。

ES模块处理循环依赖的情况

ES模块在处理循环依赖的情况时,会采取一种特殊的机制来解决这个问题,这个机制被称为“引入赋值”。

当一个模块被第一次执行时,它会被初始化为一个未完成的状态。这意味着导入的模块只包含模块的接口,而模块的内容暂时为空。在处理循环依赖时,ES模块系统会检测到循环依赖并在其中一个模块未完成时暂停执行。

当另一个模块需要导入暂停执行的模块时,ES模块系统会返回一个接口对象,该对象是一个空对象,只包含导出的接口,而真正的内容将在依赖的模块执行完毕后被添加到该对象中。

这种机制确保了循环依赖时模块系统的稳定性和效率。虽然循环依赖在模块设计中应该尽量避免,但当不可避免时,ES模块系统的引入赋值机制能够成功解决循环依赖问题。

块的导入顺序是否会影响ES模块的实例化过程

以上就是文章全部内容了,如果喜欢这篇文章的话,还希望三连支持一下,感谢!

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小纯洁w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值