繁体   English   中英

变量的继承无效

[英]Inheritance of variable doesn't work

如果我在Javascript中使用原型继承,则方法在子类中可用,但父级的成员是共享的。 为什么是这样?

例如,我正在从商店扩展2个数据结构类。

function Store() {
    this._store = [];
    this._index = -1;
}

Store.prototype.addData = function (val) {
    this._index++;
    this._store[this._index] = val;
};

Store.prototype.toString = function() {
    return "Store: [" + this._store + "]";
};

// inherits from Store
function DS1() {
}

DS1.prototype = new Store();
DS1.prototype.constructor = DS1;

现在,如果我使用2个DS1实例,它们将使用相同的存储数据。 这是为什么?

var ds1 = new DS1();
ds1.addData(2);
console.log(ds1.toString());  // Prints 2

var ds2 = new DS1();
ds2.addData(3);
console.log(ds2.toString()); // Prints 3

console.log(ds1.toString()); // Prints 3 and NOT 2.

这就是为什么不建议new用于prototype原因之一。 问题是当您的Store构造函数运行时,才会创建一个新的唯一_data数组。 您的Store构造函数只能在DS1.prototype = new Store();运行一次 DS1.prototype = new Store(); 这意味着所有new DS1()实例共享相同的_data数组。

这是一个根据我不同答案改编而成的相关示例。 假设每个Store都有一个伪唯一的随机id属性:

var Store = function() {
    // each Store instance has a random id
    this.id = Math.random();
}
Store.prototype.addData = function() { /* ... */ }

然后,您希望DS1Store继承:

var DS1 = function() {
    this.something = 5;
}
DS1.prototype = new Store();  // this is bad

var ds1 = new DS1();
console.log(ds1.id);

var ds2 = new DS1();
console.log(ds2.id);  // same as ds1!

坏消息DS1实例现在都共享相同的id DS1.prototype.id DS1.prototype = new Store();上一次设置一次DS1.prototype = new Store(); ,这就是所有DS1实例从其获取id地方。

相反,您希望在每次运行DS1构造函数代码时都运行Store构造函数代码,而不是在设置DS1原型时仅运行一次:

var DS1 = function() {
    Store.call(this);  // set parent constructor properties on `this` new DS1 obj
    //...
}

// DS1 prototype inherits from Store prototype, not Store instance
DS1.prototype = Object.create(Store.prototype);

This is because in Javascript object are not copied by value but only by reference 。现在,子代(此处为ds1,ds2)和父代的原型指向同一对象,当子代修改原型时,父代获得更改,因此兄弟姐妹 可以通过创建空函数F()将其原型设置为父构造函数的原型来实现Inheritance in javascript

    function extend(Child, Parent) {
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}

这样,您可以通过简单地使用extend(ds1, Store)来继承; 继承与原型链

Store.call(this)添加到您的DS1 “类”中。 之后,您可以开始为构造函数中的DS1特定属性分配值。

正如评论中所说,所有孩子都使用相同的对象作为原型。 这就是原型继承的工作方式。

这种继承的原型对象代表子对象的方法和变量的备用存储。

当您从d1d2调用/获取var时,它会查看它们是否具有addData 他们没有。 然后,js查找__prototype。 嘿, new Store在那里! 它有addData吗? 是! 叫...

重要的是,一次调用new Store ,因此创建的对象代表您父母的所有孩子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM