[英]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() { /* ... */ }
然后,您希望DS1
从Store
继承:
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
特定属性分配值。
正如评论中所说,所有孩子都使用相同的对象作为原型。 这就是原型继承的工作方式。
这种继承的原型对象代表子对象的方法和变量的备用存储。
当您从d1
或d2
调用/获取var时,它会查看它们是否具有addData
。 他们没有。 然后,js查找__prototype。 嘿, new Store
在那里! 它有addData
吗? 是! 叫...
重要的是,一次调用new Store
,因此创建的对象代表您父母的所有孩子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.