为什么这个javascript继承会导致引用共享数组?

为什么这个javascript继承会导致引用共享数组?,javascript,oop,prototype,Javascript,Oop,Prototype,我有一个基础班 function Base(){ this.children = new Array(); } Base.prototype.Add = function(child){ this.children.push(child) } function Sub1(){...} Sub1.prototype = new Base(); function Sub2(){...} Sub2.prototype = new Base(); 那我怎么会这么做呢 var S1_

我有一个基础班

function Base(){
    this.children = new Array();
}
Base.prototype.Add = function(child){
    this.children.push(child)
}

function Sub1(){...}
Sub1.prototype = new Base();

function Sub2(){...}
Sub2.prototype = new Base();
那我怎么会这么做呢

var S1_1 = new Sub1();
var S1_2 = new Sub1();
S1_1.Add(new Sub2());

由于某种原因,S1_2也有一个子元素,并且包含与我添加到S1_1中的子元素相同的信息。

这是因为原型继承就是这样工作的。所有
Sub1
对象都继承自一个公共
Base
对象。因为
Base
对象持有该数组,所以所有
Sub1
实例都共享该数组

换句话说,当您询问每个
Sub1
对象的
.children
属性时,他们会发现自己并不拥有这样的属性,因此会在继承的原型上查找它。由于它们继承自同一原型对象,因此使用相同的数组


对于每个
Sub1
都有自己的数组,您应该在
Sub1
构造函数中定义它

function Base(){
    this.children = new Array();
}
Base.prototype.Add = function(child){
    this.children.push(child); // `this` will be whatever object invoked the method
}

function Sub1(){
    this.children = [];
}
Sub1.prototype = new Base();

function Sub2(){
    this.children = [];
}
Sub2.prototype = new Base();

您没有获取使用此定义的基本变量的
所有权
/副本创建子组件时,您可以使用:

function Sub1(){
  Base.call(this);
}
该代码所做的是使用Sub1实例作为
this
上下文调用Base


关于原型行为的更多信息可以在这里找到:

为什么要将
Base
对象分配给
prototype
?+1-“因为基本对象保存数组”更好:使用
Sub1.prototype=object.create(Base.prototype)设置继承
。使用父实例作为原型仅在不需要任何参数时有效。@FelixKling IE 8似乎没有Object.create。我添加了处理构造函数参数,并在将原型设置为以下答案时不调用“父”构造函数:使用goog。inherit@HMR对于这个简单的用例,一个就足够了。@HMR不,它不会出现在(myObject中的hh)的
,只会出现在(对象中的hh)的
。它被添加为对象构造函数的自有属性。