Standard builtins' prototypes and toString

Allen Wirfs-Brock allen at
Thu Jun 19 10:28:19 PDT 2014

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.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list