Bound instance-function vending (was RE: Arrow binding)

Axel Rauschmayer axel at
Sat Apr 28 22:24:05 PDT 2012

The following two rules should be everything one has to know regarding callable entities, in
1. Method: `this` is an implicit parameter => use a method definition.
2. Non-method function: `this` is not an implicit parameter => use an arrow function.

In this light, I’d rewrite Kevin’s code slightly, because, conceptually, `localStorage ` is a non-method function:
  const localStorage = (obj) => {

    Object.extend(obj, {
I think Angus’ most important point is this:

> Yes, people get confused by this binding; even though it is not hard to learn the rules, and I know them very well, I still trip over them sometimes. But unless we are going to introduce a "hella strict" mode that reverts all previous rules of |this| binding, yet another rule will just add to the morass.

It would be my hope that we can replace all previous rules with the two rules above. `apply` will mostly be replaced by the spread operator, `call` will mostly be replaced by calling a value. Some code such as `forEach` implementations that previously needed to use `call` to simulate lexical scoping don’t need a `thisValue` parameter for array functions.

Then the question remains: What else is possibly confusing? Using function* as a name for generators might be problematic.

> Most of the "yay, fat arrow" comments I've seen from the dev community are celebrating its brevity, I expect many of the authors have zero knowledge of the lexical binding implications (why would they, unless they came from CoffeeScript?). Now matter how much we justify fat arrow behavior as part of  a long term vision, to many it is going to be a hidden, and unwanted side effect.

True. I would ague that partitioning callable entities into the two categories mentioned at the beginning is natural and will allow you to forget about binding rules.

I am not saying that the transition from the old rules to the new rules will be entirely painless, but if the new rules are simple, that pain is worth it, IMHO. Library code might need to go to extra lengths to help normal developers with the transition (error messages, different behavior, tool functions, etc.) and – to be explicit – might need a predicate such as `isArrowFunction` (which should only ever be used under the hood and thus would not increase confusion for library *users*).

Dr. Axel Rauschmayer
axel at


More information about the es-discuss mailing list