JavaScript将对象作为属性继承
我现在拥有的是一个对象,比如b,它继承了另一个对象,比如a。在对象a中,我有一个对象作为属性(值)。为了澄清问题:JavaScript将对象作为属性继承,javascript,inheritance,Javascript,Inheritance,我现在拥有的是一个对象,比如b,它继承了另一个对象,比如a。在对象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
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中,我将“value”对象的“val”属性设置为另一个值。正如预期的那样,设置了该值(值现在为“b”)
当我创建另一个对象时,比如说c,我希望得到原始值(“值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
我想在超类中使用对象作为属性,因为大多数值都是相同的,但有时它们必须更改。尽管是一个新实例,但仍然有一个引用
1) 这是JavaScript的某种设计缺陷吗?
2) 如何解决此问题?这是预期的行为。在构造函数中,
this.value
引用与a.prototype.value
相同的对象。您可以使用新值覆盖this.value
(这将使a.prototype
及其属性保持不变),但如果您修改this.value.val
,您将修改a.prototype.value
的val
属性
我不知道你所说的“设计弱点”是什么意思,所以我无法回答(1)。这就是JavaScript原型继承的工作方式
至于如何解决这个问题,我认为你需要给我们展示一个更具体的例子,因为我不认为有一个简单的一刀切的解决方案。可以通过使用深度复制而不是Object.create来解决这个问题(不过,根据您如何进行深度复制,您可能会丢失原型上的任何方法,如果原型有)。简单地说,如果您需要修改原型属性的属性,您将遇到这样的情况
可能更好的解决方案是为每个实例提供一组单独的数据值。让您的所有实例共享同一组数据值会在您的情况中造成混乱
初始化的构造函数中的属性:
var a = function () {
this.value = {
val: "value a"
};
};
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);
};
然后您可以从b
和c
的构造函数调用该构造函数:
var a = function () {
this.value = {
val: "value a"
};
};
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);
};
这是预期的行为。在构造函数中,this.value
引用与a.prototype.value
相同的对象。您可以使用新值覆盖this.value
(这将使a.prototype
及其属性保持不变),但如果您修改this.value.val
,您将修改a.prototype.value
的val
属性
我不知道你所说的“设计弱点”是什么意思,所以我无法回答(1)。这就是JavaScript原型继承的工作方式
至于如何解决这个问题,我认为你需要给我们展示一个更具体的例子,因为我不认为有一个简单的一刀切的解决方案。可以通过使用深度复制而不是Object.create来解决这个问题(不过,根据您如何进行深度复制,您可能会丢失原型上的任何方法,如果原型有)。简单地说,如果您需要修改原型属性的属性,您将遇到这样的情况
可能更好的解决方案是为每个实例提供一组单独的数据值。让您的所有实例共享同一组数据值会在您的情况中造成混乱
初始化的构造函数中的属性:
var a = function () {
this.value = {
val: "value a"
};
};
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);
};
然后您可以从b
和c
的构造函数调用该构造函数:
var a = function () {
this.value = {
val: "value a"
};
};
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答案中,您可以通过以下方式进行操作:
这里,“value”是“a”的属性,而不是a。在“a”和“c”构造函数中,您创建了新的、单独的“a”,因此每次都会得到一个新的“值a”。它的缺点是,您需要为所有“a”实例花费更多内存
我的答案基于此:要添加到JLRIS答案中,您可以通过以下方式进行操作:
这里,“value”是“a”的属性,而不是a。在“a”和“c”构造函数中,您创建了新的、单独的“a”,因此每次都会得到一个新的“值a”。它的缺点是,您需要为所有“a”实例花费更多内存
我的答案基于此:对象。创建(a.prototype)
创建一个全新的对象,其[prototype]
指向a.prototype
。
新的ObjectB
和ObjectC
是全新的对象,它们的[prototype]
分别指向c.prototype
<代码>b.原型
哪个是
上面的新空对象带有[prototype]
指向a.prototype
在b构造函数中
尝试将属性value.val
设置为“b”,但ObjectB没有这样的属性值
。javascript然后研究了b原型,它再次
空对象,但在它的[prototype]
中有链接到另一个对象,即a.prototype
。该对象具有属性值
,因此将其设置为value.val=“b”
对于ObjectC,链接是相同的,唯一的区别是您正在查找属性值
。Javascript查找[prototype]
链中的每个对象,直到找到值属性,该属性位于a.prototype
对象中
这不是javascript的设计弱点,而是它的优点。javascript不是OOP语言。对象。创建(a.prototype)
用它的[prototype]
指向a.prototype
创建一个全新的对象。
新的ObjectB
和ObjectC
是全新的对象,它们的[prototype]
分别指向c.prototype
<代码>b.原型
哪个是
上面的新空对象带有[prototype]
指向a.prototype
在b构造函数中