Must built-in prototypes also be valid instances? (Was: Why DataView.prototype object's [[Class]] is "Object"?)
allen at wirfs-brock.com
Sun Sep 30 11:19:14 PDT 2012
On Sep 30, 2012, at 9:47 AM, Brendan Eich wrote:
> Brendan Eich wrote:
>> The main thing I missed there is the prefixing of "~" on any tag naming a core language built-in constructor. What's this for? Why not for DOM built-ins too?
> This step:
> v. If tag is any of "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", or "String" then let tag be the string value "~" concatenated with the current value of tag.
> Also: why no Error subclasses, e.g. SyntaxError?
To further explain the workings of the proposed revisions to Object.prototype.toString
If the this value is undefined, return "[object Undefined]".
If the this value is null, return "[object Null]".
Let O be the result of calling ToObject passing the this value as the argument.
If O has a [[NativeBrand]] internal property, let tag be the corresponding value from Table 27.
Let hasTag be the result of calling the [[HasProperty]] internal method of O with argument @@toStringTag.
If hasTag is false, let tag be "Object".
Let tag be the result of calling the [[Get]] internal method of O with argument @@toStringTag.
If tag is an abrupt completion, let tag be NormalCompletion("???").
Let tag be tag.[[value]].
If Type(tag) is not String, let tag be "???".
If tag is any of "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", or "String" then let tag be the string value "~" concatenated with the current value of tag.
Return the String value that is the result of concatenating the three Strings "[object ", tag, and "]".\
Lines 1-3 are exactly like ES5.1
Line 4 looks for well known kinds objects that are a [[Class]] internal property defined by ES<=5.1. They are the instances of the Math and JSON objects, argument objects and instances of Function, Array, String, Number, Boolean, Date, RegExp, and Error. These are the only objects that are specified as having a [[NativeBrand]] internal method. The set isn't extensible. The values from the table are the [[Class]] values defined in ES5.1. Note that in ES<=5.1 all of the nativeError objects (TypeError, etc.) have the [[Class]] value "Error"
Line 5 and its sub-lines takes care of all other objects.
Line 5.a first looks to see if the object has @@toStringTag property, if not "Object" is used as the tag value and that's the end of the story.
Line 5.c.i retrieves the value of the @@toStringTag. Note that this property could be a get accessor that could throw an exception. In ES<=5.1 Object.prototype.toString never throws, so throwing would be an incompatible change. Instead of throwin g line 5.c.ii inserts "???" as the tag value as an indicator that the "name" of the object class could no be determined. It also does this if the value returned from [[Get]] of @@toStringTag is not a string.
Line 5.c.v is dealing with the ES5 requirement that "host objects" not reuse the listed [[Class]] values for anything other than the specified built-ins. This version of toStrimg extends the spirit to that restriction to all user or implementation defined tag values. It does this by prepending a "~" in front of those values if they appear as a tag value. Note that ES5.1 includes "Object" in this list so I also included it. But, I actually think it probably should be in the censored list.
WRT, DOM and other "host objects". The intent is that just like user code, they would use @@toStringTag extension point to parameterize toString rather than whatever implementation dependent [[Class]] extension mechanism they are currently working.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss