[英]JavaScript inherit object as property
我目前拥有的是一个对象b,它继承了另一个对象a。 在对象a中,我有一个对象作为property(value)。 要清除问题:
var a = (function(){});
a.prototype.value = {
val : "value a"
};
var b = (function(){
this.value.val = "b";
alert("object b: " + this.value.val);
});
b.prototype = Object.create(a.prototype);
b.prototype.constructor = a;
new b(); // alerts "object b: b"
到现在为止还挺好。 在对象b中,将“值”对象的“ val”属性设置为另一个值。 如预期的那样,已设置该值(现在的值为“ b”)。
当我创建另一个对象时,假设c,我期望得到原始值('value a')。
不是这种情况。 我确定这是适当的对象引用。
var a = (function(){});
a.prototype.value = {
val : "value a"
};
var b = (function(){
this.value.val = "b";
alert("object b: " + this.value.val);
});
var c = (function(){
alert("object c: " + this.value.val);
});
b.prototype = Object.create(a.prototype);
b.prototype.constructor = a;
c.prototype = Object.create(a.prototype);
c.prototype.constructor = a;
var ObjectB = new b(); // alerts "object b: b"
var ObjectC = new c(); // alerts "object c: b", I want that "object b: value a" is displayed
http://jsfiddle.net/eb6dsgv9/1/
我想将对象用作超类中的属性,因为大多数值将相同,但有时必须更改。 尽管是新实例,但仍然存在引用。
1)这是JavaScript的某种设计弱点吗? 2)我该如何解决?
这是预期的行为。 在构造函数中, this.value
与a.prototype.value
引用相同的对象。 您可以使用新值覆盖 this.value
(这将使a.prototype
及其属性保持不变),但是如果您修改this.value.val
那么您将修改a.prototype.value
的val
属性。
我不知道您所说的“设计弱点”是什么意思,所以我无法回答(1)。 这只是JavaScript原型继承的工作方式。
至于解决方法,我认为您需要向我们展示一个更具体的示例,因为我认为没有简单的“一刀切”的解决方案。 可以通过使用深层副本而不是Object.create来解决(尽管取决于您执行深层副本的方式,您可能会丢失原型上的任何方法,如果有的话)。 简而言之,如果您需要修改原型属性的属性,则会遇到这种情况。
可能更好的解决方案是为每个实例分别设置一组数据值。 让所有实例共享同一组数据值会在您的情况下造成混乱。
在初始化属性a
类的构造函数:
var a = function () {
this.value = {
val: "value a"
};
};
然后可以从b
和c
的构造函数中调用该构造函数:
var b = function () {
b.prototype.constructor.call(this);
this.value.val = "b";
console.log("object b: " + this.value.val);
};
var c = function () {
c.prototype.constructor.call(this);
console.log("object c: " + this.value.val);
};
要添加到JLRishe答案,您可以通过以下方式使其工作:
http://jsfiddle.net/eb6dsgv9/3/
var a = (function(){
this.value = {
val : "value a"
}
});
var b = (function(){
a.call(this);
this.value.val = "b";
alert("object b: " + this.value.val);
});
var c = (function(){
a.call(this);
alert("object c: " + this.value.val);
});
var ObjectB = new b();
var ObjectC = new c();
在这里,“值”是“ a”的属性,而不是a.prototype。 在“ a”和“ c”构造函数中,您将创建新的单独的“ a”,因此每次都会获得一个新的“值a”。 缺点是您为所有“ a”实例花费更多的内存。
我的回答基于此: Javascript属性继承
Object.create(a.prototype)
创建一个全新的对象,其[prototype]
指向a.prototype
。 您的新ObjectB
和ObjectC
是全新的对象,它们的[prototype]
指向c.prototype
resp。 b.prototype
是您上面的新空对象, [prototype]
指向a.prototype
。
在您的b constructor
您尝试将属性value.val
设置为“ b”,但是value.val
没有这样的属性value
。 javascript然后查看b原型,该原型仍然是空对象,但在[prototype]
指向另一个对象a.prototype
。 该对象具有属性value
因此将其设置为value.val = "b"
。
如果使用ObjectC,链接是相同的,唯一的区别是您正在寻找属性value
。 Javascript查找[prototype]
链中的每个对象,直到找到a.prototype
对象中的value
属性。
不是javascript的设计弱点,实际上是它的强项。 javascript不是OOP语言。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.