我最近一直在使用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的实例。
有什么正确的/更好的方法来构建模块来实现我想要的?
是否有更好的方法在模块间共享变量?
需要最小变化的解决方案是扩展模块。导出而不是重写它。
A.js -应用程序入口点和模块,使用方法做从b.js*
_ = require('underscore'); //underscore provides extend() for shallow extend
b = require('./b'); //module `a` uses module `b`
_.extend(module.exports, {
do: function () {
console.log('doing a');
}
});
b.do();//call `b.do()` which in turn will circularly call `a.do()`
B.js -模块使用方法做从a.js
_ = require('underscore');
a = require('./a');
_.extend(module.exports, {
do: function(){
console.log('doing b');
a.do();//Call `b.do()` from `a.do()` when `a` just initalized
}
})
它将工作和生产:
doing b
doing a
虽然这段代码将不起作用:
a.js
b = require('./b');
module.exports = {
do: function () {
console.log('doing a');
}
};
b.do();
b.js
a = require('./a');
module.exports = {
do: function () {
console.log('doing b');
}
};
a.do();
输出:
node a.js
b.js:7
a.do();
^
TypeError: a.do is not a function
你可以很容易地解决这个问题:在你需要使用module.exports的模块中任何其他东西之前,只需导出你的数据:
classA.js
class ClassA {
constructor(){
ClassB.someMethod();
ClassB.anotherMethod();
};
static someMethod () {
console.log( 'Class A Doing someMethod' );
};
static anotherMethod () {
console.log( 'Class A Doing anotherMethod' );
};
};
module.exports = ClassA;
var ClassB = require( "./classB.js" );
let classX = new ClassA();
classB.js
class ClassB {
constructor(){
ClassA.someMethod();
ClassA.anotherMethod();
};
static someMethod () {
console.log( 'Class B Doing someMethod' );
};
static anotherMethod () {
console.log( 'Class A Doing anotherMethod' );
};
};
module.exports = ClassB;
var ClassA = require( "./classA.js" );
let classX = new ClassB();
重要的是不要重新分配模块。导出您已经被给予的对象,因为该对象可能已经被给予周期中的其他模块!只需在模块内分配属性。导出和其他模块将看到它们出现。
所以一个简单的解决方案是:
module.exports.firstMember = ___;
module.exports.secondMember = ___;
唯一的缺点是需要重复module.exports。很多次了。
类似于lanzz和setec的回答,我一直在使用以下模式,它感觉更像是声明性的:
module.exports = Object.assign(module.exports, {
firstMember: ___,
secondMember: ___,
});
object .assign()将成员复制到已经分配给其他模块的exports对象中。
=赋值在逻辑上是冗余的,因为它只是一个设置模块。出口到自己,但我使用它,因为它帮助我的IDE (WebStorm)识别firstMember是这个模块的属性,所以“转到->声明”(Cmd-B)和其他工具将从其他文件工作。
这个模式不是很漂亮,所以我只在需要解决循环依赖关系问题时使用它。
它非常适合于显示模式,因为您可以轻松地从对象中添加和删除导出,特别是在使用ES6的属性简写时。
Object.assign(module.exports, {
firstMember,
//secondMember,
});