6

对于以下代码:

function Mammal(){
    this.hair = true;
    this.backbone = true;
    return this;
}

function Canine(){
    this.sound= 'woof';
    return this;
}
Canine.prototype = new Mammal(); 

function Dog(name){
    this.tail=true;
    this.name=name;
    return this; 
}
Dog.prototype = new Canine();

var aspen = new Dog('Aspen');

var aspenProto = aspen.__proto__

Firebug (Firefox) 想告诉我aspenProto的是Mammal{},而 Chrome 说的是Canine{}.

谁能告诉我为什么它们显示不同,是否有其他人遇到过这个问题?

4

1 回答 1

4

事实(学分转到@IHateLazy):

aspenProto.constructorMammal。这是因为constructor实际上是 Mammal.prototype 的一个属性,在方法创建时设置。Canine.prototype.constructor 不是Canine,因为原型(持有constructor财产)被 覆盖new Mammal()

测试:

aspen.constructor = function Hello(){}; // aspen is Hello in Firebug,
                                        // Dog in Chrome
aspen.constructor.name = "test"         // still Hello in Firebug,
                                        // name is also Hello in both
aspen.constructor = function(){};       // aspen is Object in Firebug
aspen.constructor.name = "test"         // still Object in Firebug
aspen.constructor = null;               // still Object and Dog

({constructor: function Hello(){}})     // Hello in Firebug AND Chrome
({constructor: function (){}})          // Object in both (not surprisingly)
({constructor:{name:"Hi"}})             // "Object" in FB, "Hi" in Chrome

x={constructor:function(){})
x.constructor.name="Hello"              // x is Object in both

x=new Object()
x.constructor=function Hello(){}        // x is Hello in both

new (function(){})()                    // Object in both
new (function(){
  this.constructor=function Hello(){}
})()                                    // Hello in both

结论:

Firebug 总是依赖对象自己的constructor属性来命名它。如果constructor是一个命名函数,它使用constructor name(不可写 - 感谢@IHateLazy)。如果该constructor属性是匿名函数或根本不是函数,那么 Firebug 会使用它"Object"

Chrome 将每个对象的实际构造函数作为内部属性。当该属性不可访问(未构造对象)或为 Object 时,它才会查看对象的constructor属性。如果构造函数是命名函数,则它使用其内部存储的名称。如果构造函数不是函数或者是匿名的,它会使用该name属性。

于 2012-12-06T22:12:50.903 回答