Object.prototype.inspect ?

Brendan Eich brendan at mozilla.com
Thu Mar 12 19:13:22 PDT 2009


On Mar 12, 2009, at 6:45 PM, Tobie Langel wrote:

> Right, that makes sense.
>
> Current behaviour in Firebug:
>
> >>> function Parent() {}
> >>> var parent = new Parent();
> >>> parent.constructor;
> Parent()

Firebug slices from toString's result, it seems.


> >>> Object.prototype.toString.call(parent);
> "[object Object]"

The [[Class]] of parent is "Object", per ES1-3.1.


> Desired behaviour:
>
> >>> Object.prototype.toString.call(child);
> "[object Child]"
> >>> Object.prototype.toString.call(parent);
> "[object Parent]"

User-defined constructor functions are not the same as native class  
constructor functions, alas. This duality is a botch of some order,  
one we've lived with for a long time.

Your proposal does not completely "fix" it, though, since the  
[[Class]] of Parent.prototype is "Object". It was not constructed by  
Parent. Maybe this is ok.

Outside of built-in classes, [[Class]] is used only for  
Object.prototype.toString. In TC39 we've argued about what [[Class]]  
means, and I've maintained it's a token corresponding in concrete  
implementation terms (vtable or equivalent) to a pile of code  
implementing a specific set of internal methods (like Array's custom  
[[Put]]).

So changing [[Class]] just to get a differnt  
Object.prototype.toString.call(obj) result is arguably wrong. Another  
option here is to add a different internal property, [[ClassName]].


> And ideally:
> >>> Child.name;
> "Child"
> >>> Parent.name;
> "Parent"

This WFM:

js> function Parent(){}
js> Parent.name
Parent


> A very naïve specification would boil down to modifying step 2 and  
> inserting a step 3 inside of 13.2.2 of the 23feb09 draft:
>
> 13.2.2 [[Construct]]
> When the [[Construct]] property for a Function object F is called  
> with a possibly empty list of
> arguments, the following steps are taken:
> 1. Let obj be a newly created native ECMAScript object.
> 2. if the name property of F is a string value set the [[Class]]  
> internal property of obj to the name property of F.
> 3. if the name property of F is not a string value set the [[Class]]  
> internal property of obj to "Object".

 From the point of view of implementors, setting the "vtable" for an  
instance is not going to be done based on a string value in a property  
of F. In either case (step 2 or 3) the same implementation code for  
generic Object behavior, appropriate to [[Class]] "Object" in ES1-3,  
will be chosen. The only difference that matters (correct me if I'm  
wrong) is the output of Object.prototype.toString.call(obj).


> There's probably a lot of issues I haven't foreseen here (on top of  
> the yet unspecified name property of functions), but it hopefully  
> helps to clarify what I was thinking about. It also avoids touching  
> the behaviour of the constructor property of the prototype object.
>
> Given that spec change, I suspect Object.getClassName(o) could be  
> desugared to Object.prototype.toString.call(object).slice(8, -1).

No, since outside of strict mode, Object is a writable, deletable  
property of the global object, and toString is writable/deletable in  
Object.prototype, and call can be shadowed, etc. etc.

Desugaring has to go from derived and optional to primitive and  
inviolable.

/be



More information about the Es-discuss mailing list