B extends A, but B.add populates A.prototype.prope

2019-02-20 17:45发布

I have one class and another that inherits property children from the first one.

function A() {}
A.prototype.children = [];

function B() {}
B.prototype = new A();
B.prototype.addChild = function(Child) {
    this.children.push(Child);
};

var b = new B();
b.addChild(new Object());

Strangely, when dumping b to console, it has no item in .children (if property .children exists at all; Chrome/Firefox), but its prototype's .children property get populated. Why is that?

2条回答
何必那么认真
2楼-- · 2019-02-20 18:37

You shouldn´t be using the prototype to store data that is for the instance. When you do this.children, there are no children in B, thus the prototype chain continues to A. As suggested by @Bergi, you should remove:

B.prototype = new A

Try defining:

function A() {
  this.children = [];
}
A.prototype.addChild = function (o) { this.children.push(o)};
var b = new A();
b.addChild({});
查看更多
叼着烟拽天下
3楼-- · 2019-02-20 18:40

There is only one children array created in your script, but it is referenced by each instance (and even B's prototype) due to inheritance. When you push to it, you will see the changes from everywhere as well.

Instead, give every instance its own array:

function A() {
    this.children = [];
}

And also, don't create only one array for all B instances to inherit from with new A - instead, use

function B() {
    A.call(this); // do everything the A constructor does on this instance
}
B.prototype = Object.create(A.prototype);
B.prototype.addChild = function(Child) {
    this.children.push(Child);
};
查看更多
登录 后发表回答