C. Scott Ananian (2014-06-11T19:45:22.000Z)
domenic at domenicdenicola.com (2014-06-20T19:28:27.649Z)
On Wed, Jun 11, 2014 at 3:27 PM, Domenic Denicola <domenic at domenicdenicola.com> wrote: > 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`: ```javascript var MyError = function(msg) { Error.call(this, 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.