@@toStringTag spoofing for null and undefined

Brendan Eich brendan at mozilla.org
Tue Jan 20 21:10:00 PST 2015

Mark S. Miller wrote:
> I understood and agree with everything (or close enough) until your last:
> On Tue, Jan 20, 2015 at 7:20 PM, Brendan Eich <brendan at mozilla.org 
> <mailto:brendan at mozilla.org>> wrote:
>     ISTM we need more definite consensus on branding to finish off
>     toStringTag in ES6.
> What we don't have is an inter-realm extensible branding mechanism.
> * typeof, Array.isArray, the ES5-compatible subset of 
> O.p.toString.call's behavior are inter-realm branding, but not extensible.
> * === and WeakMap provide extensible branding, but not in a way that 
> is usable inter-realm.
> * the rest of O.p.toString.call's behavior, i.e., the toStringTag 
> mechanism, is an inter-realm extensible labeling mechanism, but isn't 
> a branding mechanism.
> Does the last bullet unask your question, or have I misunderstood?

Not sure what my question is, referenced in your last sentence. The call 
for more definite branding thinking for ES7 before we nail down 
toStringTag for ES6? That's not a question :-P.

Anyway, toStringTag in draft ES6 is not a branding mechanism, but I 
agree with Jordan that this is a problem! People have been using 
O.p.toString.call for brand tests, whether we like it or not.

Allen's right that we don't want to make things worse by paving a 
cowpath toward "bad branding", but is the ES6 draft's 
neither-fish-nor-fowl toStringTag situation truly better? I think not.

Surgically removing toStringTag API surface is worth another look. We'd 
be no worse, ignoring the DOM and other specs that build on the core 
ECMA-262 spec, than we were with ES5.

Idea: we could let those other specs use @@toStringTag as an extension 
mechanism, but ES6 would not expose it to userland via 
Symbol.toStringTag, nor would ES6 do any "~"-prefixing. We'd rely on 
WHATWG and W3C spec authors to play nice and not spoof core built-in 

What to do about `class MyArray extends Array {...}`, where one wants 
"[object MyArray]" from O.p.toString.call on an instance of MyArray? ES6 
class syntax could set @@toStringTag under the hood, another bit of 
magic for which no desugaring (in the Felleisen 
translation-not-compilation sense) yet exists, akin to super. Grist for 
the ES7 mill.

This seems the safest play to me at the moment, and it gets rid of the 
prefixing and configurability issues, but not the whitelist. The 
whitelist rather becomes a blacklist of names that cause an early error, 
e.g. for `class Array {...}`. Errors are more future-friendly, 
especially early errors. We can perhaps relax some later.

Would this be too restrictive, in terms of throwing on friendly mocks 
such as `class RegExp {...}` that wraps a bona fide JS regexp? Perhaps, 
but it still seems safer. We need to finish ES6 without overcommitting 
to, and over-specifying, stuff we may regret later.


More information about the es-discuss mailing list