为什么这段 node.js 循环引用的代码片段可以正常工作?
PHPz
PHPz 2017-04-17 14:43:03
[Node.js讨论组]

A 模块代码:

console.log(' 开始加载 A 模块');
var b = require('./b.js');
console.log('in a, b is ', b);

exports.func = function() {
  console.log('调用 A 模块成功');
};

console.log('A 模块加载完毕');

B 模块代码:

console.log(' 开始加载 B 模块');
var A = require('./a.js');
console.log('in b, a is ', A);

exports.callAmodule = function() {
  A.func();
}
console.log('B 模块加载完毕');

运行如下代码,先加载 A 模块,制造循环引用:

var a = require('./a.js');
var b = require('./b.js');
b.callAmodule();

运行结果如下:

开始加载 A 模块
开始加载 B 模块
in b, a is  {}
B 模块加载完毕
in a, b is  { callAmodule: [Function] }
A 模块加载完毕
调用 A 模块成功

两个模块产生循环引用,执行时:B 模块中的 A 是没加载完全的。但是 callAmodule 方法却成功执行了 A 模块的方法,这不符合我的预期,另外一段类似的循环引用,的确产生了问题,是符合我预期的代码见: http://selfcontained.us/2012/...

不清楚两段类似的循环引用代码,却结果完全不一样的原因

PHPz
PHPz

学习是最好的投资!

全部回复(3)
迷茫

你把A模块里的代码改成下面这样就会出现预期的报错:

module.exports = {
  func: function () {
    console.log('调用 A 模块成功');
  }
};

理解这一点需要明白 exports 和 module.exports 的区别:

  1. exports 是指向的 module.exports 的引用

  2. module.exports 初始值为一个空对象 {},所以 exports 初始值也是 {}

  3. require() 返回的是 module.exports 而不是 exports

在 A 模块还没有加载完时,就开始加载 B 模块,此时,var a = require('./a.js') 返回的 A 模块的 module.exports 是 {}。B 模块加载完成后,继续回到 A 模块完成 A 模块的加载。

如果在 A 模块里,通过 exports.func 来定义方法,就会动态地给 A 模块的 module.exports 加入 func 方法,后边 A.func()调用该方法时,是没有问题的。

如果在 A 模块里,用 module.exports = { func: ...} 方式来定义方法,由于加载 B 模块时,var a = require('./a.js') 已经返回 A 模块的 module.exports 是 {},后边加载完 B 模块后再继续加载 A 模块也不会改变 A 模块导出的值为 {},所以,调用A.func() 就会出现 TypeError: A.func is not a function 的报错。

怪我咯

1、加载和执行不同
2、加载模块是“同步”的

PHP中文网

当main.js加载a.js的时候,a.js依次需要加载b.js.在这时,b.js试着去加载a.js.为了防止一个无穷的循环(loop),一个未完成的a.js的副本的exports导出对象被返回到b.js模块.然后b.js完成加载,然后他的exports导出对象被提供给a.js模块.
看这个,因为你这里a.js 和a.js都有一个exports
http://blog.csdn.net/kingvike...

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号