On Jan 21, 2015, at 12:51 PM, Jordan Harband wrote:
> To reiterate, I see the issue as boiling down to two questions:
> 1) Should builtins have their @@toStringTag value configurable?
> Can anyone provide a use case, or any value, to allowing this? If not, I
> think they should not be configurable. I'd be very interested to hear why it
> would aid debugging, or help Domenic's DOM concerns (which are totally valid
> and admirable), or help with extensibility?
There's something that I think you may have missed. As currently spec'ed for
ES6 legacy built-ins do not have @@toStringTag properties. Instead O.p.toString
uses internal branding to tag them, just like in ES<6. If you add a
@@toStringTag to those legacy built-ins the anti-spoofing logic still applies.
Classically the way TC39 as approached all issues like this is to say that an
application (such as SES) that depends upon this level of integrity are
responsible for freezing the appropriate properties (or entire prototype
objects).
For built-in properties where uninformed modification by a naive programmer
could cause unexpected consequences, ES6 defines them as writable:
false/configurable: true. All of the @@toStringTag methods defined by ES6 fall
into that category. The intent is that this prevents accidental over-write of
those those properties via directly assignment. You have to go out of your way
and use Object.defineProperty to modify them.
>
> 2) Should non-builtin JS values be able to pretend to be builtins via
> spoofing @@toStringTag?
> If the answer to (1) is "every builtin's @@toStringTag is not configurable"
> then I think I'm actually comfortable with a value explicitly pretending to
> be an Array, for example, and risking the consequences of doing that
> incorrectly. In this scenario, dropping the prefixing entirely makes sense to
> me.
I'd still appreciate it if you could provide some more concrete example where
this style of branding would make a difference a to one of your applications.
For example, if Map had the same level O.p.toString branding integrity as Date.
What would you do with it.
For example, if you coded:
```js
if ({}.toString.call(obj) ==='[object Map]') {
//what would you do here?
} else {
// that is different from what you would do here?
}
```
>
> However, if the answer to (1) is "builtins' @@toStringTag is configurable",
> then this question needs to be modified.
>
> I see no need to drop @@toStringTag, and little need to keep the prefixing at
> all, if all builtins (not just ES5 ones) have a nonconfigurable @@toStringTag.
>
> It also suddenly occurs to me that the ability to pretend to be a builtin
> will in fact be very useful to me, personally, for the es*-shims.
>
> Is there anyone who wouldn't be happy with "all builtins' @@toStringTag is
> not configurable" and "drop the ~ prefixing completely"?
BTW, It is possible to do a built-in realm independent brand check most of the
ES6 built-ins. Something I've long intended to take the time to do is to write
how to do a reliable, non-distructive brand check for there ones where this is
possible. Here is a start:
```js
// all Objects and methods referenced below are assumed to be the actual named
intrinsic. You will probably ned to capture references to the intrinsic
instead of directly
// referencing them as shown below.
function isMap(m) { //similarly for Set, WeakMap, WeakSet
try {
Map.prototype.size.call(m);
return true;
} catch () {return false}
}
function isDataView(d) {
try {
DataView.prototype.buffer.call(d);
return true;
} catch () {return false}
}
function isPromise(p) {
try {
Promise.prototype.then.call(p);
return true;
} catch () {return false}
}
function isTypedArray(a) { //any TypedArray instance
try {
Uin32Array.prototype.buffer.call(a);
return true;
catch () {return false}
function isUint8ArrayArray(a) { //for exmaple
try {
return Uin8Array.prototype[Symbol.toStringTag].call(a)==="Uint8Array"; ?
true : false;
} catch () {return false}
}
function isDate(d) { //for exmaple
try {
Date.prototype.getDay.call(d);
return true;
} catch () {return false}
}
//exercise, finish this list. Identity any where this sort of technique won't
work.
```
What does the above checks tell you. They tell you for each of the tested
built-ins (well, except for the individual typed arrays) whether the built-ins
defined for it will work on the tested object. Nothing more, nothing less.
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss