javascript - 继承属性中使用的对象字面量会更改该类的所有实例

标签 javascript inheritance object-literal

我有以下代码 (ObjA),它按我预期的方式工作,实例“a1”具有与“a2”相同的属性,但具有不同的值。

function ObjA() {
    this.objLiteral = {};
    this.propA = 0;
}

var a1 = new ObjA();
a1.objLiteral['hello'] = 3;
a1.propA = 1.5;

var a2 = new ObjA();
a2.objLiteral['goodbye'] = 4;
a2.propA = 2;

a1 和 a2 的调试器信息:
http://www.flickr.com/photos/76617756@N02/6879283032/

接下来,我有以下继承自 ObjA 的 ObjB。实例“b1”和“b2”具有相同的属性,但属性 propA 和 propB 的值不同,但出于某种原因,objLiteral 在两者中是相同的,就好像它引用的是同一对象一样。

ObjB.prototype = new ObjA();
ObjB.prototype.constructor=ObjB;

function ObjB() {
    this.propB = 2;
}

var b1 = new ObjB();
b1.objLiteral['hello2'] = 6;
b1.propA = 4;
b1.propB = 5;

var b2 = new ObjB();
b2.objLiteral['goodbye2'] = 8;
b2.propA = 6;
b2.propB = 7;

b1 和 b2 的调试器信息:
http://www.flickr.com/photos/76617756@N02/6879283088/

有人可以帮助我了解发生了什么吗?我必须做什么才能得到我期望的结果? 非常感谢您的帮助。

最佳答案

好吧,对象 b1b2 都具有相同 原型(prototype),即 ObjA 的实例:

ObjB.prototype = new ObjA();

因此他们继承并可以访问它的属性。 b1.objLiteralb2.objLiteral 引用同一个对象:

enter image description here

> b1.objLiteral === b2.objLiteral
  true

要解决这个问题,您必须为每个实例创建一个新对象。这通常是通过在“子”构造函数中调用“父”构造函数来完成的:

function ObjB() {
    ObjA.call(this);
    this.propB = 2;
}

ObjA.call(this) 将调用 ObjA 并且在该函数内,this 将引用传递给 call [MDN] 的参数,在本例中是 ObjB 的新实例:

enter image description here

如您所见,objLiteral 现在是每个实例的属性:

> b1.objLiteral === b2.objLiteral
  false

首先要避免这种混淆,应避免将父构造函数的实例设置为子构造函数的原型(prototype)。如果父构造函数需要实例特定参数怎么办?在这种情况下,您会向 ObjA 传递什么?

最好将子构造函数的原型(prototype)设置为父构造函数的原型(prototype)(具有一级间接),并像上面那样调用父构造函数:

function inherit(Child, Parent) {
    var Tmp = function() {};
    Tmp.prototype = Parent.prototype;
    Child.prototype = new Tmp();
    Child.prototype.constructor = Child;
}

inherit(ObjB, ObjA);

Tmp 以防止在您稍后扩展 Child.prototype 时扩展 Parent.prototype


关于propA:

它“有效”,因为您正在为其分配一个新值。

在将属性分配给 x.objLiteralx.propA 之后,这里又是对象。您可以看到对象没有自己的 objLiteral 属性,而是有自己的 propA:

enter image description here

相反,如果您为 objLiteral 分配一个新值,例如通过

b1.objLiteral = {hello: 42};

b1 现在将拥有自己的属性 objLiteral,它隐藏了继承的属性:

enter image description here

关于javascript - 继承属性中使用的对象字面量会更改该类的所有实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9917734/

相关文章:

javascript - Mootools 1.3 和 Fx.Styles

java - 构造函数 - 找不到符号

c# - 避免从基类继承所有东西

c++ - 无法在派生类的子命名空间中实现方法

javascript - 如何过滤数组循环中的数据

javascript - 对象文字模式: can't access a data attribute when binding events

Javascript 在函数内部使对象字面量等于 {},

javascript - 如何使用 l20n.js 指示在浏览器中呈现哪种语言?

javascript - $state.go - 更新 url

javascript - 错误: Target container is not a DOM element react/react-redux