Arrow Functions
We will first describe the fat arrow syntax. Then we will discover the main advantage of arrow functions: context binding.
Fat Arrow Syntax
Let's write an ES5 function to sum two numbers.
var sum = function( a, b ) {
return a + b;
};
Using fat arrows ( =>
), we will rewrite the same function in two steps.
Step 1: replace the function
keyword with a fat arrow.
var sum = ( a, b ) => {
return a + b;
};
Step 2: if the return value of the function can be described by one expression, and the function body has no side-effects, then we can omit the braces and the return
keyword too.
var sum = ( a, b ) => a + b;
If a function only has one argument, parentheses are not needed on the left of the fat arrow:
var square = a => a * a;
Use case: syntactic sugar, more compact way of writing functions.
Context binding
In ES5, function scope often requires the awkward and unmaintainable self = this
trick or the usage of context binding. Observe a simple example for the latter.
var Ball = function( x, y, vx, vy ) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.dt = 25; // 1000/25 = 40 frames per second
setInterval( function() {
this.x += vx;
this.y += vy;
console.log( this.x, this.y );
}.bind( this ), this.dt );
}
b = new Ball( 0, 0, 1, 1 );
Arrow functions come with automatic context binding. The lexical value of this isn't shadowed by the scope of the arrow function. Therefore, you save yourself thinking about context binding.
var Ball = function( x, y, vx, vy ) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.dt = 25; // 1000/25 = 40 frames per second
setInterval( () => {
this.x += vx;
this.y += vy;
console.log( this.x, this.y );
}, this.dt );
}
b = new Ball( 0, 0, 1, 1 );
Use case: Whenever you want to use the lexical value of
this
coming from outside the scope of the function, use arrow functions.
Don't forget that the equivalence transformation for fat arrows is the following:
// ES2015
ARGUMENTS => VALUE;
// ES5
function ARGUMENTS { return VALUE; }.bind( this );
The same holds for blocks:
// ES2015
ARGUMENTS => {
// ...
};
// ES5
function ARGUMENTS {
// ...
}.bind( this );
In constructor functions, prototype extensions, it typically does not make sense to use fat arrows. This is why we kept the Ball
constructor a regular function.
We will introduce the class
syntax later to provide an alternative for construction functions and prototype extensions.
Exercises
Exercise 1: Write an arrow function that returns the string 'Hello World!'
.
Exercise 2: Write an arrow function that expects an array of integers, and returns the sum of the elements of the array. Use the built-in method reduce
on the array argument.
Exercise 3: Rewrite the following code by using arrow functions wherever it makes sense to use them:
var Entity = function( name, delay ) {
this.name = name;
this.delay = delay;
};
Entity.prototype.greet = function() {
setTimeout( function() {
console.log( 'Hi, I am ' + this.name );
}.bind( this ), this.delay );
};
var java = new Entity( 'Java', 5000 );
var cpp = new Entity( 'C++', 30 );
java.greet();
cpp.greet();