今天遇到一个极其蛋疼的情况,两个js模块,相互循环引用,造成一个bug。
// a.js
import { SomeB } from './b.js'
export const SomeA = 'aaa:' + SomeB
// b.js
import { SomeA } from './a.js'
export const SomeB = 'bbb:' + SomeA
接下来我在一个文件中使用模块b:
// c.js
import { SomeB } from './b.js'
console.log(SomeB)
你知道会得到什么结果吗?总之是得到错误的结果。在chrome中直接运行会直接报错,说a.js中的SomeB未定义。这……
其实这是真的。因为a.js和b.js相互引用,导致的结果就是,无论是谁,在执行的时候,都需要另外一个模块加载完成才能进行自己的解释。这就很蛋疼:
c.js -> b.js -> a.js -> b.js -> a.js ...
而js解释器一般会灵活处理,即不会死循环的去如此解释,而是在发现循环的时候,就直接结束,即:
c.js -> b.js -> a.js $
但是,当a.js需要b.js所带来的上下文时,实际上b.js还没有被解释,因为b.js依赖a.js的解释结果,因此,在a.js中,SomeB被认为是not defined,这已经不是TypeError,而是ReferenceError,也就是在上下文中,该变量未被声明。
因此,千万不要循环引用啊,切记切记。