Go to ES6Fiddle, paste in this ES5 code, and run it:

var obj = {
  fn: function() {
    console.log(typeof this);
    return new Promise(function(res, rej) {
      console.log(typeof this);
      setTimeout(res, 1000);
    });
  }
};

obj.fn();

This will output the following.

object
undefined

Next, paste in this ES6 code.

const obj = {
  fn: function()  {
    console.log(typeof this);
    return new Promise((res, rej) => {
      console.log(typeof this);
      setTimeout(res, 1000);
    });
  }
};

obj.fn();

This will output the following.

object
object

What’s going on here? In ES6, we’re using an arrow function. As Dr. Axel Rauschmayer points out regarding arrow functions in ES6:

Their this is picked up from surroundings (lexical). Therefore, you don’t need bind() or that = this, anymore.

This is really powerful. I’ve done both bind() and that=this quite a bit in my lifetime of ES5. You might be wondering however what you’d do if there’s ever a time that you need to access the inner this. As far as I can tell, this just isn’t possible with arrow functions. Dmitri Pavlutin writes:

this in JavaScript is a powerful feature. It allows to change the context depending on the way a function is called. Frequently the context is the target object on which invocation happens, making the code more natural. It says like “something is happening with this object”.

However the arrow function binds the context statically on declaration and is not possible to make it dynamic. It’s the other side of the medal in a situation when lexical this is not necessary.

Sometimes, the old school ES5 syntax is a must, apparently. Good luck with lint rules that don’t like this traditional function expression!