Standard builtins' prototypes and toString
Till Schneidereit
till at tillschneidereit.net
Thu Jun 19 11:03:04 PDT 2014
On Thu, Jun 19, 2014 at 7:46 PM, C. Scott Ananian <ecmascript at cscott.net>
wrote:
> While we're on the topic, shall we discuss `valueOf()`? Should it get the
> same treatment?
> --scott
>
Oh, yes: I always considered the `toString` discussion to really be about
`valueOf`, too.
> On Jun 19, 2014 1:28 PM, "Allen Wirfs-Brock" <allen at wirfs-brock.com>
> wrote:
>
>>
>> On Jun 19, 2014, at 3:18 AM, Till Schneidereit wrote:
>>
>> On Thu, Jun 19, 2014 at 1:39 AM, Allen Wirfs-Brock <allen at wirfs-brock.com
>> > wrote:
>>
>>>
>>> On Jun 18, 2014, at 4:12 PM, Brendan Eich wrote:
>>>
>>> > Allen Wirfs-Brock wrote:
>>> >> The spec. current says throw for this Symbol.prototype case. The
>>> (reasonable) opposing view is that toString should never throw. Other than
>>> the protoype-is-not-an-instance it all about unlikely edge cases where
>>> toString methods are applied to the wrong kind of object.
>>> >
>>> > js> Object.create(null).toString()
>>> > typein:1:0 TypeError: Object.create(...).toString is not a function
>>> >
>>> > It happens. Better to catch that error (Symbol.prototype flowing into
>>> an implicit conversion) early?
>>>
>>> which is pretty much the approach the ES6 spec. has taken WRT toString
>>> up to now. Tension between catching invalid iplicit toString conversions
>>> and reliable toString for debugging.
>>>
>>
>> I'd posit that there are three different cases for toString:
>> 1) (explictly or implicitly) calling foo.toString, where `foo` is any of
>> the objects that, by default, exist in a JS global without any user code
>> having run
>> 2) (explicitly or implicitly) calling foo.toString, where `foo` is some
>> content script-generated object
>> 3) explicitly calling bar.toString.call(foo), where `foo` and `bar` are
>> arbitrary objects
>>
>> The current (ES5) state of things is that 1) can never throw, while both
>> 2) and 3) might. The current ES6 draft would move 1) over into the latter
>> camp. I think *that* is the crucial thing to prevent. It's just wrong for
>> the language to essentially say "here's a bunch of objects. They have
>> methods. But don't call all of them. Finding out which ones aren't allowed
>> to be called is left as an excercise to the reader."
>>
>> Theoretically, Scott's #d still hold the most appeal to me. However, I
>> don't think it works in a multi-Realm world, hence "theoretically". Given
>> that, it's #b or #c, where, again, I don't much care which one it'll be.
>>
>>
>> Or even in a single Realm world, it isn't clear how:
>> (class extends Date {}).prototype.toString()
>> would recognize that is is dealing with a prototype rather than a Date
>> instance.
>>
>> I basically agree with you conclusion. An the conserve thing to do is to
>> try to minimize legacy compat. To me, that says that for Date, Number,
>> Boolean, String, RegExp we should do (c). For new kinds of objects that
>> don't exist in ES5 and which have internal state dependent toStrings we
>> should do (b).
>>
>> I'll update the spec. accordingly.
>>
>> Note that for the (c) cases this introduces a different breaking change:
>> ES5 specifies that String.prototype.toString.call({}) throws a TypeError
>> but the (c) based change will return the empty string for that case.
>> Hopefully, that is a change the web can live with.
>>
>
Same for Date.prototype.toString({}) as mentioned above, yes. I'm
cautiously optimistic about these changes.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20140619/62a2b71e/attachment.html>
More information about the es-discuss
mailing list