Do ES2015 Classes "not autobind"?

I had similar questions. Methods within your class will be able to reference other methods in the same class, because they are part of the same context (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this).

This example shows that methods in a class can access properties on this without being bound in the constructor: http://jsbin.com/tapokotahi/1/edit?js,console,output. The renderElements method is not bound, but is accessing this.state.

The class methods need to be bound (or defined as arrow functions) when they are passed into event handlers, because the execution context changes from that of the class to that of the event handler.

I agree it seems confusing when we read the React docs and they tell us we need to bind the methods in the constructor, but that is only necessary when passing the methods to React's event handlers such as onClick.


The reason why React keeps mentioning autobinding is because React.createClass was autobinding all methods. And that method was the only way to create components.

People, especially those not that familiar with JavaScript, got used to passing methods to other components and this would "magically" work. This feature disappeared with using native ES6 classes, so they needed to emphasize the difference.

But yes, ES6 classes are basically just syntactic sugar for constructor functions + prototype. The methods are not bound to the object:

class Foo {
  bar() {}
}

const foo = new Foo();

console.log(foo.hasOwnProperty('bar')); // false
console.log(typeof Foo === 'function'); // true
console.log(Foo.prototype.hasOwnProperty('bar')); // true


You can make you ES6 class methods auto-bind with a little boiler-plate in the constructor:

function autobind() {
  for (let prop of Object.getOwnPropertyNames(Object.getPrototypeOf(this))) {
    if (prop === 'constructor' || typeof this[prop] !== 'function') continue;
    this[prop] = this[prop].bind(this);
  }
}

class Test {
  constructor() {
    autobind.call(this);
    this.message = 'hello all!';
  }
  method1(){ return this.method2(); }
  method2(){ console.log(this.message);}
}
let test = new Test();
let b = test.method1;
b();

UPDATE:

I have since found a Babel Plugin that translates the upcomping ES Class Fields & Static Properties which you can use for functions that need to be bound to the this

class Bork {
    //Property initializer syntax
    instanceProperty = "bork";
    boundFunction = () => {
      return this.instanceProperty;
    }

    //Static class properties
    static staticProperty = "babelIsCool";
    static staticFunction = function() {
      return Bork.staticProperty;
    }
}

let myBork = new Bork;

//Property initializers are not on the prototype.
console.log(myBork.__proto__.boundFunction); // > undefined

//Bound functions are bound to the class instance.
console.log(myBork.boundFunction.call(undefined)); // > "bork"

//Static function exists on the class.
console.log(Bork.staticFunction()); // > "babelIsCool"