Must built-in prototypes also be valid instances? (Was: Why DataView.prototype object's [[Class]] is "Object"?)

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Oct 1 13:40:05 PDT 2012


On Oct 1, 2012, at 12:39 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>> Line 5.c.v is dealing with the ES5 requirement that "host objects" not reuse the listed [[Class]] values for anything other than the specified built-ins. This version of toStrimg extends the spirit to that restriction to all user or implementation defined tag values.  It does this by prepending a "~" in front of those values if they appear as a tag value.  Note that ES5.1 includes "Object" in this list so I also included it. But, I actually think it probably should be in the censored list.
> 
> This is weird.
> 
> ES5 wanted to help SES and similar languages use some kind of
> 
>  original_Object_prototype_toString_call(anyObject).slice(8,-1)
> 
> and not be subject to spoofing.
> 
> Adding @@toStringTag to enable DOM self-hosting runs directly counter to this goal.
> 
> Prefixing "~" to core-language built-in classes (save "Object"?) does not resolve the conflict if there are spoofing hazards in other built-ins such as DOM objects as typically implemented in browsers.
> 
> Mark, can you weigh in? I had not heard of this "~"-prefixing idea.

Let me try explaining this again, if we provide an extension point for parameterizing Object.prototype.toString and it allows arbitrary objects to produce, for example, "[Object Array]
" or "[Object Function]" then it invalidates all legacy uses of Object.prototype.toString as nominal type check for those specific built-ins.  The "~" prefix is one way to avoid this problem.

DOM implementation usage is a separate issue, although arguably a motivating one making Object.prototype.toString extensible.  W3C specifications have consistently tried to use [[Class]] as an extension point for parameterizing Object.prototype.toString and implementations have supported them by providing implementation specific mechanisms that allow DOM implementations provide a [[Class]] value to Object.prototype.toString.

The proposed ES6 spec. for Object.prototype.toString recognizes the utility of such an extension point.  I would certainly be used by a ES-host DOM implementation but it would also be useful  for anyone else defining class-like abstractions where they want Object.prototype.toString.

The little quicks like the "~" prefix and the exception eating are simply what is necessary to formalize this extensibility model while still preserving the behavior of existing code that depends upon object.prototype.toString as a reliable mechanism to test for instances of the ES<=5.1 built-ins.

Allen


More information about the es-discuss mailing list