原型继承,Firefox与Chrome的区别

时间:2012-12-06 20:40:52

标签: javascript

以下代码:

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)想告诉我aspenProtoMammal{},而Chrome则说Canine{}

任何人都可以告诉我为什么他们显示不同,如果有其他人遇到过这个问题?

1 个答案:

答案 0 :(得分: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属性。