事实(学分转到@IHateLazy):
aspenProto.constructor是Mammal。这是因为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属性。