循环引用实例化

时间:2016-08-21 14:53:57

标签: 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的引用吗?

1 个答案:

答案 0 :(得分:1)

我建议将问题移到AB的构造函数中。

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

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;

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

如果有AB合法地将.b.a设置为null的情况,您可以使用undefinednull区分这些情况,并相应地更改构造函数:

function A(b)
{
    this.b = b === undefined ? new B(this) : b;
}
function B(a)
{
    this.a = a === undefined ? new A(this) : a;
}

如果AB需要其构造函数的其他参数,或者由于某些其他原因而不应该自己构造另一个BA,那么您可以将它们传递给{来自创建范围的{1}}实例(因为它包含thisa字段,其值仅在访问时确定,而不是在bA构建时):

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); A无法完全访问容器对象,则可以创建要在其位置使用的中间对象,例如:

B

如果由于某种原因这也是不可接受的,那么您唯一的选择是稍后通过手动分配或通过设置器功能更改var aProxy = { a: null }; var bProxy = { b: null }; this.a = aProxy.a = new A(bProxy); this.b = bProxy.b = new B(aProxy); a.b的值。