Facts (loans go to @IHateLazy):
aspenProto.constructor Mammal . This is because constructor is actually the Mammal.prototype attribute set at the time the method was created. Canine.prototype.constructor not Canine , since the prototype (containing the constructor property) has been rewritten with new Mammal() .
Tests:
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
Conclusion:
Firebug always relies on the constructor object's own property to name it. If constructor is a named function, it uses constructor name (which is not writable - thanks @IHateLazy). If the constructor property is an anonymous function or not a function at all, Firebug uses "Object" instead.
Chrome stores the actual constructor of each object as an internal property. Only if this property is not available (the object was not created) or the Object object, does it look at the constructor object. If the constructor is a named function, it uses its internally stored name. If the constructor is not a function or is anonymous, it uses the name property.
source share