2016-08-21 107 views
1

我想要实例两类这两者是互相依赖的,像这样:循环引用实例

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

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

+0

在'A'和'B'的构造函数中做。例如。对于'A',如果它通过'null',则设置'this.b = new B(this);'。当'B'传递'a!= null'时,递归结束。交换'A'和'B'的方法相同。 – Siguza

+2

我认为唯一的方法是在实例化两个对象后使用setter来完成循环。 – Claudiu

回答

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自己,你可以通过他们的this实例从创建范围(因为持有ab领域,其值将只确定访问的时候,而不是当AB构造):

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); 

如果AB并不意味着有充分的交流塞斯的容器对象,你可以创建一个中介对象在其场所使用,如:

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

如果这也是出于某种原因不能接受,那么你唯一的选择是后来改的a.bb.a值通过手动分配或通过setter功能。

+2

但请注意,这种方法将两个类本身紧密结合在一起,而不是让它们的容器完成工作并传递实例。 – Bergi

+0

这是它不适合我的原因。我认为我必须由制定者来完成任务,即使它有点脏。 – landunder

+0

@landunder明确地说,前两种方法将类组合在一起,后两种方法(其中A和B通过一个容器)不这样做。 – Siguza