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

Reply via email to