Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 循环引用实例化_Javascript_Oop_Circular Reference - Fatal编程技术网

Javascript 循环引用实例化

Javascript 循环引用实例化,javascript,oop,circular-reference,Javascript,Oop,Circular Reference,我想实例化两个相互依赖的类,如下所示: this.a = null; this.b = null; this.a = new A({ b: this.b } this.b = new B({ a: this.a } 问题是如果我这样做b如果我把它交给构造函数,它将为null。我如何以“优雅”的方式解决这个鸡或蛋的问题?或者我必须在通过方法实例化后将引用设置为b。我建议将问题转移到a和b的构造函数 在这种情况下,您可以利用条件(间接)递归: function A(b) { th

我想实例化两个相互依赖的类,如下所示:

this.a = null;
this.b = null; 
this.a = new A({
  b: this.b
}
this.b = new B({
  a: this.a
}

问题是如果我这样做
b
如果我把它交给构造函数,它将为null。我如何以“优雅”的方式解决这个鸡或蛋的问题?或者我必须在通过方法实例化后将引用设置为
b

我建议将问题转移到
a
b
的构造函数

在这种情况下,您可以利用条件(间接)递归:

function A(b)
{
    this.b = b || new B(this);
}
function B(a)
{
    this.a = a || new A(this);
}
通过使用
|
,您可以确保对
a(this)
B(this)
的调用本身不会分别创建另一个
B
/
a
,从而结束“鸡/蛋”问题

然后你可以像这样使用它们

this.a = new A();
this.b = this.a.b;

如果存在
A
B
合法地将其
.B
.A
设置为
null
,则可以使用
未定义的
null
来区分这些情况,并相应地更改构造函数:

function A(b)
{
    this.b = b === undefined ? new B(this) : b;
}
function B(a)
{
    this.a = a === undefined ? new A(this) : a;
}
如果
A
B
需要其他参数来构造它们的构造函数,或者出于其他原因不应该构造另一个
B
A
本身,则可以从创建范围向它们传递
实例(因为它包含
a
b
字段,其值仅在访问时确定,而不是在构建
a
b
时确定):

如果
A
B
并不意味着对容器对象具有完全访问权限,则可以创建用于其位置的中间对象,如:

var aProxy = { a: null };
var bProxy = { b: null };
this.a = aProxy.a = new A(bProxy);
this.b = bProxy.b = new B(aProxy);

如果出于某种原因,这也是不可接受的,那么您唯一的选择就是以后通过手动赋值或通过setter函数来更改
a.b
b.a
的值。

a
b
的构造函数中执行此操作。例如,对于
a
,如果通过
null
,则设置
此值。b=新b(本)当
B
被传递一个
a!=null
时,递归结束。与
a
B
交换的方式相同。我认为唯一的方法是在实例化两个对象后使用setter来完成循环。但是请注意,这种方法将两个类紧密地结合在一起,而不是让它们的共同ntainer完成工作并传递实例。这就是它对我不起作用的原因。我认为我必须通过setter进行赋值,尽管它有点脏。@landunder说得很清楚,前两种方法将类绑定在一起,后两种方法(其中a和B被传递为容器)没有。
function A(container)
{
    this.container = container;
    // Access B via this.container.b
}
function B(container)
{
    this.container = container;
    // Access A via this.container.a
}
this.a = new A(this);
this.b = new B(this);
var aProxy = { a: null };
var bProxy = { b: null };
this.a = aProxy.a = new A(bProxy);
this.b = bProxy.b = new B(aProxy);