Standard builtins' prototypes and toString

Till Schneidereit till at
Thu Jun 19 11:03:04 PDT 2014

On Thu, Jun 19, 2014 at 7:46 PM, C. Scott Ananian <ecmascript at>

> 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>
> 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
>> > 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, 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{}) 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: <>

More information about the es-discuss mailing list