关于循环引用是面试的考点之一,在工作中遇到这种问题确实很少见,但是有必要了解一下。
CommonJS模块的循环加载_循环引用

根据上面的图我们可以看到,入口文件main.js引用了a.js,模块a.js引用了b.js,模块b.js引用了a.js,这就是是循环引用。

循环引用会导致内存溢出,进程终止吗?
回答:不会

出现循环引用代码依旧可以运行,那么他是如何运行的呢?

main.js

const a = require('./a');
console.log(a)

a.js

console.log('导入b之前')
const b = require('./b'); // 注意,此时a.js代码就停在这里,等待b.js执行完毕,再往下执行。
console.log(b)
console.log('导入b之后')

module.exports = '我是a模块'

b.js

console.log('导入a之前')
const a = require('./a');  // 发生了"循环引用",系统会去a.js模块对应对象的exports属性取值
console.log(a) // 因为a.js还没有执行完,只执行第一行和第二代码,所以此时a的值是一个空对象
console.log('导入a之后')

module.exports = '我是b模块'

CommonJS的做法是,一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。

导入b之前
导入a之前
{}
导入a之后
我是b模块
导入b之后
我是a模块