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

_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to