Javascript 变量的继承不';行不通
如果我在Javascript中使用原型继承,这些方法在子类中可用,但来自父类的成员是共享的。为什么会这样 例如,我正在从我的存储扩展2个数据结构类Javascript 变量的继承不';行不通,javascript,Javascript,如果我在Javascript中使用原型继承,这些方法在子类中可用,但来自父类的成员是共享的。为什么会这样 例如,我正在从我的存储扩展2个数据结构类 function Store() { this._store = []; this._index = -1; } Store.prototype.addData = function (val) { this._index++; this._store[this._index] = val; }; Store.pr
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;
现在,如果我使用两个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.
这就是为什么要使用。问题是,只有当
存储
构造函数运行时,才会创建新的唯一\u数据
数组。您的Store
构造函数只在DS1.prototype=newstore()中运行一次
这意味着所有新DS1()
实例共享相同的\u数据
数组
下面是一个改编自。假设每个存储
都有一个伪唯一的、随机的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=newstore()行上设置一次代码>,这就是所有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);
这就是为什么要使用。问题是,只有当存储
构造函数运行时,才会创建新的唯一\u数据
数组。您的Store
构造函数只在DS1.prototype=newstore()中运行一次
这意味着所有新DS1()
实例共享相同的\u数据
数组
下面是一个改编自。假设每个存储
都有一个伪唯一的、随机的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=newstore()行上设置一次代码>,这就是所有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);
添加Store。将(this)
调用到您的DS1
“类”。之后,您可以开始为构造函数中的DS1
特定属性赋值。添加Store。将(this)
调用到DS1
的“类”。之后,您可以开始在构造函数中为特定于DS1的属性赋值。正如注释中所述,所有孩子都使用同一对象作为原型。这就是原型继承的工作原理
这种继承中的原型对象作为子对象的方法和变量的备用存储
当您从d1
或d2
调用/获取var时,会查看它们是否有addData
。他们没有。然后js研究了uuu原型。嘿,新店就在那里!它是否有一个addData
?对叫它
重要的是,newstore
只调用一次,因此创建的对象代表您父母的所有孩子。正如评论中所说,所有孩子都使用相同的对象作为原型。这就是原型继承的工作原理
这种继承中的原型对象作为子对象的方法和变量的备用存储
当您从d1
或d2
调用/获取var时,会查看它们是否有addData
。他们没有。然后js研究了uuu原型。嘿,新店就在那里!它是否有一个addData
?对叫它
重要的是,newstore
只调用一次,因此创建的对象代表父对象的所有子对象。这是因为在Javascript中,对象不是通过值复制的,而是通过引用复制的。
。现在,当子对象修改原型时,子对象(这里是ds1、ds2)和父对象的原型指向同一个对象,父母得到了改变,兄弟姐妹也得到了改变继承可以通过创建空函数F()来实现,将其原型设置为父构造函数的原型,如下所示
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)
即可继承 这是因为在Javascript中,对象不是通过值复制的,而是通过引用复制的。
现在,子对象(这里是ds1、ds2)和父对象的原型指向同一个对象,当子对象修改原型时,父对象得到更改,同级对象也得到更改继承可以通过创建空函数F()来实现,将其原型设置为父构造函数的原型,如下所示
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)
即可继承 DS1的所有实例都共享相同的数据,因为只有一个DS1.prototype.\u store
,ever.No。2不同的数据结构。用Java术语来说,DS1和DS2都扩展了存储,我希望它们都有自己的存储阵列。@aspillers删除了导致混淆的DS2。所以我有两个DS1的实例。为什么它们共享相同的数据?不,因为DS1
构造函数没有设置\u存储
属性。只有Store
构造函数可以这样做,您只能调用它一次。如果您想了解更多关于原型的工作原理和构造函数函数的作用,您可以在下面的回答中了解它:DS1的所有实例都共享相同的数据,因为只有一个DS1.prototype.\u Store
,ever.No。2不同的数据结构。用Java术语来说,DS1和DS2都扩展了存储,我希望它们都有自己的存储阵列。@aspi