【问题标题】:Prototype inheritance. obj->C->B->A, but obj.constructor is A. Why?原型继承。 obj->C->B->A,但是obj.constructor是A。为什么?
【发布时间】:2011-05-13 14:52:10
【问题描述】:
var print = function(text){
  document.write(text);
  document.write("</br>");
}

var A = function(){
}
A.prototype.name="A";

var B = function(){
}
B.prototype = new A();
B.prototype.name="B";

var C = function(){
}
C.prototype = new B();
C.prototype.name="C";

obj = new C();
print(obj.name);
print(obj.constructor.prototype.name);
print(obj.constructor == A);

这段代码给出了下一个输出:

C
A
true

为什么这里的 obj.constructor 是 A 而不是 C?

【问题讨论】:

  • 构造函数属性在原型对象中定义,当你分配它时,你分配它的所有成员。必须定义任何想要具有不同值的成员,否则您将继承构造函数、toString、valueOF 以及原型包含的任何其他内容。
  • 谢谢,我已经意识到了

标签: javascript


【解决方案1】:

this code sample 中所见,使用继承时您必须手动重置.constructor 属性,否则当您调用new A()new B() 时您的构造函数被覆盖:

B.prototype = new A();
B.prototype.constructor = B; // need this line to fix constructor with inheritance

这是一个工作示例:http://jsfiddle.net/93Msp/

希望这会有所帮助!

【讨论】:

  • 有趣 - 知道为什么这是可取的行为吗?
  • 鉴于 JavaScript 中的 OO 是一个大黑客,这样的事情是可以预料的。
【解决方案2】:

为了清晰的画面:

在链中

 obj->"new B()"->"new A()"   // where obj is the same as "new C()"

只有"new A()" 对象具有constructor 属性。所有其他对象都从原型链中获得constructor 属性。

在代码中:

 var A = function(){
 }
 A.prototype.name="A";
 // A had not create "constructor" property for "new A()" 
 // so, looking at the prototype
 // According to ECMAScript spec 13.2.10
 // A.prototype.constructor == A
 // thus
 // "new A()".constructor == A

 var B = function(){
 }
 B.prototype = new A();
 B.prototype.name="B";
 // B had not create "constructor" property for "new B()" 
 // looking at the prototype
 // B.prototype is "new A()" 
 // as shown above 
 // "new A()".constructor == A
 // thus
 // B.prototype.constructor == A
 // and at the end
 // "new B()".constructor == A

 var C = function(){
 }
 C.prototype = new B();
 C.prototype.name="C";
 // C had not create "constructor" property for "new C()"/"obj" 
 // looking at the prototype
 // C.prototype is "new B()" 
 // looking up to "new B()".prototype
 // "new B()".prototype is "new A()" as shown above
 // "new A()".constructor == A
 // and finally
 // C.prototype.constructor == A

 obj = new C();
 print(obj.name);
 print(obj.constructor.prototype.name);
 print(obj.constructor == A);

所以正如 mellamokb 所写,我们应该覆盖(创建,如果更准确的话)constructor 属性。

【讨论】:

    【解决方案3】:

    我认为这篇文章很好地解释了原型继承中的构造函数

    http://phrogz.net/js/classes/OOPinJS2.html

    【讨论】:

    • 确实如此。那是我链接的同一页面。
    猜你喜欢
    • 2014-03-29
    • 1970-01-01
    • 2019-08-07
    • 2015-11-20
    • 2011-08-01
    • 2019-10-27
    • 2012-06-14
    • 1970-01-01
    • 2019-12-18
    相关资源
    最近更新 更多