Arrow functions in ES6 / ES2015
Older Article
This article was published 10 years ago. Some information may be outdated or no longer applicable.
This post first appeared on Full Stack Training
Arrow functions are new in ES2015. They let you write terser function expressions (fewer lines), but there’s a bigger difference: arrow functions don’t create their own this. Let’s look at what that means.
ES5
Best to learn by example. Imagine a website with a button that greets people:
<button id="greet">Greet</button>
Now imagine a JavaScript object that defines a person with some properties, including a function that greets them:
var person = {
name: 'Joe',
age: 21,
greet: function greet() {
btn.addEventListener('click', function () {
console.log(this);
return this.display('Well hello there ' + this.name);
});
},
display: function display(message) {
console.log(message + '. You are ' + this.age + ' years old.');
},
};
A click event listener is wired up inside the greet function. Looking at return this.display('Well hello there ' + this.name);, you’d expect this.name to point to person.name and this.display to call the function on the same object.
That’s not what happens. Running this code throws: “Uncaught TypeError: this.display is not a function”. The console.log(this) inside the event listener returns a reference to the button itself. A new this gets created for every function definition, and we’ve got an anonymous function on the event listener. The button DOM element has no “name” or “display” property.
Binding this or var that = this
Two ways to fix this (it’s not really a bug, it’s how this works). First, call .bind() on the event listener. bind() lets you change what this references:
greet: function greet() {
btn.addEventListener('click', (function () {
console.log(this);
return this.display('Well hello there ' + this.name);
}).bind(this));
},
Second option: capture this in a variable and use that variable inside the event listener’s scope:
greet: function greet() {
var that = this;
btn.addEventListener('click', (function () {
console.log(that);
console.log(this);
return that.display('Well hello there ' + that.name);
}));
},
Arrow functions to the rescue
With ES2015 arrow functions, you don’t need .bind(), .call(), .apply(), or the var that = this trick. Arrow functions lexically bind this:
var person = {
name: 'Joe',
age: 21,
greet: function () {
btn.addEventListener('click', () =>
this.display('Well hello there ' + this.name)
);
},
display: function (message) {
console.log(message + '. You are ' + this.age + ' years old.');
},
};
Conclusion
Arrow functions let you write terser function expressions and they lexically bind this. Fewer headaches when writing OO-style JavaScript.