繁体   English   中英

JavaScript继承对象作为属性

[英]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"

http://jsfiddle.net/qqmtb846/

到现在为止还挺好。 在对象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.valuea.prototype.value引用相同的对象。 您可以使用新值覆盖 this.value (这将使a.prototype及其属性保持不变),但是如果您修改this.value.val那么您将修改a.prototype.valueval属性。

我不知道您所说的“设计弱点”是什么意思,所以我无法回答(1)。 这只是JavaScript原型继承的工作方式。

至于解决方法,我认为您需要向我们展示一个更具体的示例,因为我认为没有简单的“一刀切”的解决方案。 可以通过使用深层副本而不是Object.create来解决(尽管取决于您执行深层副本的方式,您可能会丢失原型上的任何方法,如果有的话)。 简而言之,如果您需要修改原型属性的属性,则会遇到这种情况。

可能更好的解决方案是为每个实例分别设置一组数据值。 让所有实例共享同一组数据值会在您的情况下造成混乱。

在初始化属性a类的构造函数:

var a = function () {
    this.value = {
        val: "value a"
    };
};

然后可以从bc的构造函数中调用该构造函数:

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);
};

http://jsfiddle.net/eb6dsgv9/6/

要添加到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 您的新ObjectBObjectC是全新的对象,它们的[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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM