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

Mark S. Miller erights at
Mon Oct 1 20:48:25 PDT 2012

On Mon, Oct 1, 2012 at 8:17 PM, Brendan Eich <brendan at> wrote:

> Mark S. Miller wrote:
>> Regarding the integrity of original as a
>> branding mechanism, I agree we need a new more general branding mechanism.
>> WeakMaps and Symbols both give us a place to hang this, but we need a
>> concrete proposal. The proposal should work both with builtins and with
>> classes. If a better branding proposal waits till ES7, then we need to
>> preserve integrity of original as a branding
>> mechanism through ES6. If this is preserved through ES6, then it probably
>> becomes too entrenched to consider retiring.
>> Were there other questions for me that I missed?
> Yes. Should (per the latest draft, Object.prototype.toString) the
> following names:
> "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON",
> "Math", "Number", "Object", "RegExp", or "String"
> and "Object" (per Allen here), and only these names, be prefixed with "~"
> when returned via [[Get]](@@toStringTag) where @@toStringTag denotes a
> spec-internal (implementation-internal) symbol?

The "~" looks very ugly to me. As I state above, I would rather we invent a
more general branding mechanism and then stop making this requirement
on original Relaxing this requirement would
still technically be a breaking change from ES5 so we need to be cautious.
But I bet we can get away with it if we do it by ES6. By ES7 it will
probably be too late.

> The idea is to uphold ES5's paragraph from Clause 15, starting
> ''The value of the [[Class]] internal property is defined by this
> specification for every kind of built-in object. The
> value of the [[Class]] internal property of a host object may be any
> String value except one of "Arguments",
> "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number",
> "Object",
> "RegExp", and "String".''
> Step 4 uses [[NativeBrand]] in preference to @@toStringTag, which enables
> the core-language built-ins to return, e.g., "Array" without fear of "~"
> being prepended.
> This two-level scheme seems like overkill, and the clause 15 intro
> restriction on host objects claiming, e.g., to be of "Function" [[Class]]
> (presumably to be updated to [[NativeBrand]]) seems unnecessary to me. If a
> host function satisfies all the observable requirements of a native one,
> why not?

If a host function satisfies *all* the observable requirements of a native
one, then it is simply misclassified. It *is* a host-provided *native*
function and should have a [[Class]] of "Function". (Allen, thank you for
getting us away from this awful "host" and "native" terminology!)

> I asked a question aimed more directly at you up-thread: why should *only*
> the above 12 or 13 names be subject to "~"-prepending when returned from an
> object that lacks [[NativeBrand]]? Are there not host objects in need of
> protection from class-spoofing?

In the ES5 timeframe, there were hard limits on how much cleanup of host
objects we could do before finalizing the spec. Given the constraints, I
think it's miraculous that we cleaned them up as much as we did. There is
one form of spoofing protection that we did enforce by these rules for host
objects, they cannot pretend to be native objects, and no native object can
pretend to be a host object.

> /be

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list