Configurability of @@toStringTag for Built-ins

Allen Wirfs-Brock allen at wirfs-brock.com
Tue Dec 16 15:42:46 PST 2014


On Dec 16, 2014, at 1:58 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>> On Dec 16, 2014, at 10:49 AM, Rick Waldron wrote:
>> 
>>> Allowing configurability of the value of a built-in object's @@toStringTag property has the (likely undesirable) side effect of making calls to Object.prototype.toString.call(o) unreliable.
>>> 
>>> Illustrated here: https://twitter.com/caitp88/status/525700685942509569
>>> 
>>> Repeated here for the purpose of discussion:
>>> 
>>>  Object.prototype.toString.call(new Map());
>>>  "[object Map]"
>>>  Object.defineProperty(Map.prototype, Symbol.toStringTag, { value: "Fish" });
>>>  // ...
>>>  Object.prototype.toString.call(new Map());
>>>  "[object Fish]"
>>> 
>>> While this won't break existing code (see: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring <https://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-object.prototype.tostring>), there should be consistency across built-ins. I propose we adopt as a rule that the @@toStringTag for all _built-ins_ is always defined as:
>>> 
>>> { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }
>>> 
>> 
>> The @@toStrngTag mechanism is, by design, unreliable for non-legacy built-ins.  TC39 decided that the legacy use of O.p.toString as a normative type test for built-ins was a practice we wanted support moving forward beyond ES5.
> 
> This led to the further complexity in ES6's O.p.toString of prepending "~" to a legacy builtin name impostors! http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring
> 
> It all hangs together but seems a bit much.

We been around this many times and had a TC39 consensus.  There is no time to go around this with TC39 again, before the final ES6 draft has to be completed.
> 
> Alternative is to make toStringTag non-configurable for all classes.

Do you mean new built-ins or also user defined classes (which don't necessarily even have names).  It's also not clear how impostures could be prevented give an open ended set of future built-in and user defined classes.

> 
>> Why do you think there should be consistency across built-ins? What about consistency between built-ins and ES defined classes?
> 
> I suspect people (some of 'em ;-) will want consistent high-integrity toStringTag.

They can make the toStringTags they care about non-configurable at startup, at the same time they capture a reference O.p.toString.

There are many things that could have been locked in in ES6, but we had a consensus that we wouldn't do that beyond making some new properties  resistant to accidental change by making them non-writable+configurable.

Allen


More information about the es-discuss mailing list