最近在做项目的时候发现在一个模块导出的时候是返回一个NEW以后实例化的对象,在其他地方使用的是同一个对象(一直以为是不用的对象,每次导入都是一个新的。。。还是太菜)。
在网上了解了ES6模块的一个基本机制,所以记录一下笔记。
ES6中模块不会重复执行
一个模块无论被多少个地方引用,引用多少次,模块内部始终只执行一次。
ES6中模块输出值的引用
在ES6中,导出输出的值会动态关联模块中的值:
1 | // count.js |
count的值是会动态变化的。
ES6模块循环依赖
import 会优先执行,跟位置无关
1 | // a.js |
import被JS引擎静态分析,会被提到模块的最前面,优先于模块中的其他部分的执行。
1 | // a.js |
(CommonJS)首先a.js加载b.js,此时a.js代码暂停在这里,执行加载b.js,在b.js中又加载a.js,但是a.js并没有加载完,所以获取到undefined,然后继续执行完以后,回到a.js正常执行。
(ES6) 首先a.js加载b.js,所以先执行b.js,而b.js又去加载a.js,这时候由于a.js已经开始执行了,所以不会重复执行,而是继续执行b.js,又a.js还未执行完,所以b.js获取到值是undefined,然后继续执行完以后,回到a.js正常执行。
CommonJS 和 ES6 的这个加载描述是在网上查阅的,还不是很懂,感觉两种方式的行为都是一样的啊= =!!
感觉CommonJS的加载方式套用在ES6,ES6的加载方式套用在CommonJS都能说的通。。CommonJS模块不也是只会加载一次嘛,套用在ES6感觉都没毛病。。。
在main.js中执行,得出并不会再去执行第二行代码b.js,原因是在执行a.js时b.js已经被加载,模块不会被重复加载。
一个关于动态引用的例子:
1 | // a.js |
按照CommonJS规范,上面的代码是无法执行的。a先加载b,然后b又加载a,这时a还没有任何执行结果,所以输出结果为null,即对于b.js来说,变量foo的值等于null,后面的foo()就会报错。
但是,ES6可以执行上面的代码,a.js之所以能够执行,原因就在于ES6加载的变量都是动态引用其所在模块的。只要引用存在,代码就能执行。
会到问题到最开始,在导出时返回new对象到操作,只有在第一次加载的时候,会执行模块中的代码,返回一个实例化以后的对象,以后的每次导入,都是第一次的结果,并不会重新在去执行一次模块的代码。
1 | // obj.js |
- 本文标题:ES6中的模块
- 创建时间:2020-03-07 15:42:09
- 本文链接:posts/b9c8.html
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!