我目前拥有的是一个对象,比如b,它继承了另一个对象,比如说a。在对象中,我有一个对象作为属性(值)。澄清事情:
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,我希望我得到原始值('值为')。
事实并非如此。我确定这是应该参考的对象。
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)我该如何解决这个问题?
答案 0 :(得分:2)
这是预期的行为。在构造函数中,this.value
引用与a.prototype.value
相同的对象。您可以使用新值覆盖 this.value
(这会使a.prototype
及其属性保持不变),但如果修改this.value.val
,则修改{{1} val
的属性。
我不知道你的“设计弱点”是什么意思所以我不能回答(1)。这就是JavaScript的原型继承的工作方式。
至于如何解决它,我认为你需要向我们展示一个更具体的例子,因为我认为没有一个简单的“一刀切”的解决方案。它可以通过使用深层副本而不是Object.create来解决(虽然取决于你如何进行深层复制,你可能会丢失原型上的任何方法,如果有的话)。简单地说,如果你需要修改原型属性的属性,你将遇到这样的情况。
可能更好的解决方案是为每个实例分别设置一组数据值。让所有实例共享同一组数据值会在您的情况下造成混乱。
初始化a.prototype.value
构造函数中的属性:
a
然后你可以从var a = function () {
this.value = {
val: "value a"
};
};
和b
的构造函数中调用该构造函数:
c
答案 1 :(得分:2)
要添加到JLR她的答案,您可以这样工作:
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();
这里,'value'是'a'的属性,而不是a.prototype。在'a'和'c'构造函数中,您创建了新的,单独的'a',因此每次都会获得一个新的'值'。它的缺点是你为所有'a'实例花费了更多的记忆。
我的回答基于此: Javascript property inheritance
答案 2 :(得分:1)
Object.create(a.prototype)
创建了一个全新的对象,其[prototype]
指向a.prototype
。
您的新ObjectB
和ObjectC
是全新的对象,其[prototype]
指向c.prototype
。这是b.prototype
上面的新空对象[prototype]
指向a.prototype
。
在b constructor
中,您尝试将属性value.val
设置为" b"但是ObjectB没有这样的属性value
。 javascript比再看看b原型
空对象,但其[prototype]
中的链接指向a.prototype
的另一个对象。该对象具有属性value
,因此设置为value.val = "b"
。
对于ObjectC,链接是相同的,唯一的区别是您正在寻找属性value
。 Javascript查找[prototype]
链中的每个对象,直到找到value
对象中的a.prototype
属性。
这不是javascript的设计弱点,实际上它是它的力量。 javascript不是OOP语言。