我最近一直在使用nodejs,仍然在掌握模块系统,所以如果这是一个明显的问题,那么很抱歉。我希望代码大致如下:
A.js(主文件与node一起运行)
var ClassB = require("./b");
var ClassA = function() {
this.thing = new ClassB();
this.property = 5;
}
var a = new ClassA();
module.exports = a;
b.js
var a = require("./a");
var ClassB = function() {
}
ClassB.prototype.doSomethingLater() {
util.log(a.property);
}
module.exports = ClassB;
我的问题似乎是我不能从ClassB的实例中访问ClassA的实例。
有什么正确的/更好的方法来构建模块来实现我想要的?
是否有更好的方法在模块间共享变量?
现在不是2015年,大多数库(例如express)已经更新了更好的模式,因此不再需要循环依赖。我建议不要使用它们。
我知道我挖出了一个老答案……
这里的问题是这个模块。exports定义在您需要ClassB之后。
(JohnnyHK的链接显示)
循环依赖关系在Node中工作得很好,它们是同步定义的。
如果使用得当,它们实际上解决了许多常见的节点问题(比如从其他文件访问express.js应用程序)
只需确保在需要具有循环依赖关系的文件之前定义了必要的导出。
这将打破:
var ClassA = function(){};
var ClassB = require('classB'); //will require ClassA, which has no exports yet
module.exports = ClassA;
这是可行的:
var ClassA = module.exports = function(){};
var ClassB = require('classB');
我一直使用这个模式来访问其他文件中的express.js应用程序:
var express = require('express');
var app = module.exports = express();
// load in other dependencies, which can now require this file and use app
博士TL;
只需使用导出。somember = somember而不是module。Exports ={//新对象}。
扩展的回答
在读完lanzz的回答后,我终于可以弄清楚这里发生了什么,所以我会就这个问题发表我的意见,扩展他的回答。
让我们来看看这个例子:
a.js
console.log("a starting");
console.log("a requires b");
const b = require("./b");
console.log("a gets b =", b);
function functionA() {
console.log("function a");
}
console.log("a done");
exports.functionA = functionA;
b.js
console.log("b starting");
console.log("b requires a");
const a = require("./a");
console.log("b gets a =", a);
function functionB() {
console.log("On b, a =", a)
}
console.log("b done");
exports.functionB = functionB;
main.js
const a = require("./a");
const b = require("./b");
b.functionB()
输出
a starting
a requires b
b starting
b requires a
b gets a = {}
b done
a gets b = { functionB: [Function: functionB] }
a done
On b, a = { functionA: [Function: functionA] }
在这里,我们可以看到b首先接收一个空对象作为a,然后一旦a完全加载,该引用将通过导出更新。functionA = functionA。如果将整个模块替换为另一个对象,则通过module。导出,那么b将失去来自a的引用,因为它将从开始指向相同的空对象,而不是指向新的对象。
如果你像这样导出:module。exports = {functionA: functionA},那么输出将是:
a starting
a requires b
b starting
b requires a
b gets a = {}
b done
a gets b = { functionB: [Function: functionB] }
a done
On b, a = {} // same empty object