ES6之Module 的加载实现(3)

4.循环加载

“循环加载”(circular dependency)指的是,a脚本的执行依赖b脚本,而b脚本的执行又依赖a脚本

这里写图片描述

通常,“循环加载”表示存在强耦合,如果处理不好,还可能导致递归加载,使得程序无法执行,因此应该避免出现

但是实际上,这是很难避免的,尤其是依赖关系复杂的大项目,很容易出现a依赖b,b依赖c,c又依赖a这样的情况。这意味着,模块加载机制必须考虑“循环加载”的情况

对于JavaScript语言来说,目前最常见的两种模块格式CommonJS和ES6,处理“循环加载”的方法是不一样的,返回的结果也不一样

4.1CommonJS模块的加载原理

CommonJS的一个模块,就是一个脚本文件。require命令第一次加载该脚本,就会执行整个脚本,然后在内存生成一个对象

这里写图片描述

上面代码就是Node内部加载模块后生成的一个对象。该对象的id属性是模块名,exports属性是模块输出的各个接口,loaded属性是一个布尔值,表示该模块的脚本是否执行完毕。其他还有很多属性,这里都省略了

以后需要用到这个模块的时候,就会到exports属性上面取值。即使再次执行require命令,也不会再次执行该模块,而是到缓存之中取值。也就是说,CommonJS模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存

4.2CommonJS模块的循环加载

CommonJS模块的重要特性是加载时执行,即脚本代码在require的时候,就会全部执行。一旦出现某个模块被”循环加载”,就只输出已经执行的部分,还未执行的部分不会输出

这里写图片描述

上面代码之中,a.js脚本先输出一个done变量,然后加载另一个脚本文件b.js。注意,此时a.js代码就停在这里,等待b.js执行完毕,再往下执行

再看b.js的代码
这里写图片描述

上面代码之中,b.js执行到第二行,就会去加载a.js,这时,就发生了“循环加载”。系统会去a.js模块对应对象的exports属性取值,可是因为a.js还没有执行完,从exports属性只能取回已经执行的部分,而不是最后的值

a.js已经执行的部分,只有一行
这里写图片描述

因此,对于b.js来说,它从a.js只输入一个变量done,值为false

然后,b.js接着往下执行,等到全部执行完毕,再把执行权交还给a.js。于是,a.js接着往下执行,直到执行完毕。我们写一个脚本main.js,验证这个过程
这里写图片描述

执行main.js,运行结果如下
这里写图片描述

上面的代码证明了两件事。一是,在b.js之中,a.js没有执行完毕,只执行了第一行。二是,main.js执行到第二行时,不会再次执行b.js,而是输出缓存的b.js的执行结果,即它的第四行

这里写图片描述

总之,CommonJS输入的是被输出值的拷贝,不是引用

4.3ES6模块的循环加载

ES6处理“循环加载”与CommonJS有本质的不同。ES6模块是动态引用,如果使用import从一个模块加载变量(即import foo from ‘foo’),那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值

这里写图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/407537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle存储过程写法(一)

Create or Replace Procedure Proc_AppendRecords(nAppendCount int -- 要添加的记录条数)asbegindeclarenstart int;nend int;beginselect NVL(max(UserID),0) into nstart from T_Test_Checkbill;nend : nstart nAppendCount;while nstart < …

列举网络芳邻的网络资源

此范例会以递归方式列举网络芳邻的网络资源&#xff0c;在此范例中会使用到 mpr.dll API 函式库的 WNetEnumResource、WNetOpenEnum、WNetCloseEnum 函式来进行网络芳邻的网络资源的列举动作。 TAPIMpr 类别为 mpr.dll API 函式库的操作类别 1: <summary> 2: …

HDU 1087

一个简单而经典的dp; 若数组a&#xff1a;1 3 2 4 则数组b&#xff1a;1 4 3 8 b[i]每一个都要向前找 合法 的最大b[x]值加上当前的a[i]; 如b[2]b[0]a[2]; #include <iostream>using namespace std;int a[1001];int b[1001];int max_b(int i){ int max10; for(int …

Vue之重命名组件

因为header本身是关键字&#xff0c;所以这里通过重命名的方式改为’v-header’

一个封装了的选项卡效果js

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv"Content-Type" content"text/html; charsetgb2312"><title>井底的蛙</title><script type"text/j…

Struts2学习笔记1

一&#xff0e;下载struts2.0.1 http://struts.apache.org/downloads.html&#xff0c;下载struts-2.0.1-all.zip&#xff0c;这个压缩包中包括了开发struts2所需的struts2-core.jar核心包以及其他struts2所依赖的JAR文件&#xff0c;另外另一些struts2的演示样例程序以及一些H…

如何在oracle中查询所有用户表的表名、主键名称、索引、外键等

使用select * from user_tables 可以查询出所有的用户表。 查所有用户的表在all_tables 主键名称、外键在all_constraints 索引在all_indexes 但主键也会成为索引&#xff0c;所以主键也会在all_indexes里面。 具体需要的字段可以DESC下这几个view&#xff0c;dba登…

Vue路径的别名

这里给’components’赋予了一个地址&#xff0c;那么在程序中引入路径的时候’components’就直接可以代替路径’../src/components’

汽车驾照分类

驾照级别分类 公安部正式发布《机动车驾驶证业务工作规范》规定&#xff0c;推出机动车驾驶证分级制&#xff0c;将驾照分为A1、A2、A3、B1、B2、C1、C2、C3、C4、D、E、F、M、N、P共15个级别。 公安部根据不同车型的驾驶难度和安全要求&#xff0c;将目前驾驶证签注的3种准驾…

uni-app附件预览

// 预览附件perviewFile(file) {console.log(点击附件, file)var strfile.previewUrlvar filTypestr.split(.)console.log(filType,filType)uni.downloadFile({url: success: function(res) {console.log(打开文档成功, res);if (res.statusCode 200) {uni.saveFile({tempFile…

简单的单级下拉菜单实现

这里用纯CSS实现一个简单的单级下拉菜单&#xff0c;鼠标划过菜单标题时显示下拉菜单。 基本思路 在菜单处于光标之下时显示菜单&#xff0c;其余时候隐藏。这个过程首先得想到 :hover 伪类来实现&#xff0c;但是直接的利用伪类还不行&#xff0c;因为普通状态下菜单隐藏了&am…

C#里面的继承

举个例子&#xff1a;有一个基类RectangleEx1 classRectangleEx2 {3 privateint_x, _y, _w, _h;4 5 publicintx6 {7 get{ return_x; }8 set{ _x value; }9 }10 publicinty11 {12 get{ return_y; }13 set{ _y value; }14 }15 publicintw16 {17 get{ return_w; }18 set{ _w value…

Vue-Router的路由实例构造配置

可以通过在创建路由实例的时候传入不同的对象来选择不同的配置&#xff0c;这里的’linkActiveClass’代表的是给被激活的<router-link>添加一个叫做’active’的类名&#xff0c;然后我们就可以在css中给被激活标签设置不同的CSS了 其余的还有

uboot中的mmc命令

一&#xff1a;mmc的命令例如以下&#xff1a; 1&#xff1a;对mmc读操作 mmc read addr blk# cnt 2&#xff1a;对mmc写操作 mmc write addr blk# cnt 3&#xff1a;对mmc擦除操作 mmc erase blk# cnt 4&#xff1a;又一次搜索mmc设备 mmc rescan 5&#xff…

对STL的string进行格式化输出

突然遇到需要对一个string类型的变量进行格式化输出&#xff0c;一时不知道怎么做。google了一下&#xff0c;终于找到了答案。 ostringstream os; os < < "abc " < < abc; string s os.str(); 所需头文件&#xff1a;#includ…

WinForm UI设计与开发思路(转)

最近一年来一直在做WinForm相关的系统&#xff0c;对WinForm的UI设计有一些想法想和大家讨论&#xff08;主要是比较忙&#xff0c;所以很多只是设想&#xff0c;还没有开发实例&#xff09; 关于WinUI&#xff0c;理想的情形应该是外观比较cool&#xff0c;能给用户良好的使用…