C. Scott Ananian ecmascript at
Wed Jun 11 12:45:22 PDT 2014

On Wed, Jun 11, 2014 at 3:27 PM, Domenic Denicola
<domenic at> wrote:
>> Of course this  can all be fixed with .bind() or a "bind" operator, but it just seems unfortunate to throw out something that's not harming the spec in favor something that might be problematic in end user code.
> This is a bit of a slippery-slope argument; the end result is that every method should have a default `this` value that it's "soft-bound" to, in order to coddle the users who might get confused.

And from my perspective, trying to fix the users' bugs for them is a
very dangerous slope indeed.  You are producing behavior that doesn't
match the user's mental model of how `this` *should* work (ie, how it
works for all other methods).  Some developer is going to get badly
confused when a falsy or unusual `this` doesn't throw a `TypeError` as
they expect (allowing them to identify and debug the problem) but
instead silently "succeeds" returning an object of an arbitrary class.

I was walking a newish JS developer through a similar issue last
night, when they wanted to know why the standard JS inheritance
doesn't work for `Error`:

var MyError = function(msg) {, msg); };
MyError.prototype = new Error();
MyError.prototype.constructor = MyError;

console.log((new MyError("foo")).message); // prints... undefined ?!

Why doesn't `message` get initialized?  Surprise, it's because in ES5
invoking `Error` as a function ignores the given `this` and
substitutes a new one, which is a brand-new instance of `Error`, and
returns *that*.  This made my developer friend cry.  (This is hacked
around in ES6 so that `class MyError extends Error` is sane.)

We shouldn't make this mistake in ES6.  Use the `this` which the
author of the code provided and don't second-guess them, or else they
will tear at their hair in confusion.

More information about the es-discuss mailing list