Posted by admin at January 15, 2020
Arrow functions – also called “fat arrow” functions, from CoffeeScript are a more concise syntax for writing function expressions. They utilize a new token, =>
, that looks like a fat arrow. Arrow functions are anonymous and change the way this
binds in functions.
Arrow functions have a single overarching structure, and then an number of ways they can be simplified in special cases.
The core structure looks like this:
(argument1, argument2, ... argumentN) => {
// function body
}
A list of arguments within parenthesis, followed by a ‘fat arrow’ (=>
), followed by a function body.
This is very similar to traditional functions, we just leave off the function
keyword and add a fat arrow after the arguments.
However, there are a number of ways to ‘sugar’ this up that make arrow functions dramatically more concise for simple functions.
First, if the function body is a single expression, you can leave off the brackets and put it inline. The results of the expression will be returned by the function. For example:
const add = (a, b) => a + b;
Second, if there is only a single argument, you can even leave off the parenthesis around the argument. For example:
const getFirst = array => array[0];
As you can see, this can lead to some very concise syntax, which we’ll highlight more benefits of later.
There are a few pieces of advanced syntax that are useful to know.
First, if you’re attempting to use the inline, single-expression syntax but the value you’re returning is an object literal. You might think this would look like:
(name, description) => {name: name, description: description};
The problem is that this syntax is ambiguous – it looks as though you’re trying to create a traditional function body.
To indicate that instead you want a single expression that happens to be an object, you wrap the object with parentheses:
(name, description) => ({name: name, description: description});
Unlike every other form of function, arrow functions do not have their own execution context
Practically, this means that both this
and arguments
are inherited from their parent function.
For example, compare the following code with and without arrow functions:
const test = {
name: 'test object',
createAnonFunction: function() {
return function() {
console.log(this.name);
console.log(arguments);
};
},
createArrowFunction: function() {
return () => {
console.log(this.name);
console.log(arguments);
};
}
};
We have a simple test object with two methods – each a function that creates and returns an anonymous function.
The difference is in the first case it uses a traditional function expression, while in the latter it uses an arrow function.
If we run these in a console with the same arguments however, we get very different results.
> const anon = test.createAnonFunction('hello', 'world');
> const arrow = test.createArrowFunction('hello', 'world');
> anon();
undefined
{}
> arrow();
test object
{ '0': 'hello', '1': 'world' }
The anonymous function has its own function context, so when you call it there is no reference available to the this.name
of the test object, nor to the arguments called in creating it.
The arrow function, on the otherhand, has the exact same function context as the function that created it, giving it access to both the argumetns and the test object.
The examples above took arguments from the left of =>
and evaluated the right-side expression with them.
Sometimes we need something a little bit more complex, like multiple expressions or statements. It is also possible, but we should enclose them in curly braces. Then use a normal return
within them.
Like this:
let sum = (a, b) => { // the curly brace opens a multiline function
let result = a + b;
return result; // if we use curly braces, then we need an explicit "return"
};
alert( sum(1, 2) ); // 3
Arrow functions, like function expressions, can be used to return an object literal expression. The only caveat is that the body needs to be wrapped in parentheses, in order to distinguish between a block and an object (both of which use curly brackets).
//ES5
var setNameIdsEs5 = function setNameIds(id, name) {
return {
id: id,
name: name
};
};
// ES6
var setNameIdsEs6 = (id, name) => ({ id: id, name: name });
console.log(setNameIdsEs6 (4, "Kyle")); // Object {id: 4, name: "Kyle"}
Comments