ES2015 (ES6) - Arrow Functions Walk-Through
Click Here For Guided Lesson
Arrow functions have a more terse syntax than regular functions (function keyword):
// regular function
let squares = [1, 2, 3].map(function (x) { return x * x });
// arrow function
let squares = [1, 2, 3].map(x => x * x);A single parameter need not be wrapped in parens:
x => { ... } // one parameter
() => { ... } // no parameters
(x, y) => { ... } // two or more parametersHowever, even though we can skip wrapping a single parameter with parens, many style guides recommend using them anyway:
(x) => { ... } // one parameterThe statement block of an arrow function behaves just like that of a regular function:
const getGrade = (score) => {
if (score === 100) return 'A+';
score = Math.floor(score / 10);
return ['F', 'F', 'F', 'F', 'F', 'F', 'D', 'C', 'B', 'A'][score];
};If there's only a single expression (not a statement), curly braces are optional:
const logThis = () => { console.log(this) };
const logThis = () => console.log(this);Arrow functions will implicitly return the result of an expression without a block (braces):
const add = (x, y) => { return x + y };
// Ideal single-statement arrow function
const add = (x, y) => x + y;
// Returns undefined (blocks are like reg functions)
const add = (x, y) => { x + y };
// Syntax error, must be an expression
const add = (x, y) => return x + y;To implicitly return a JS object, wrap it in parens to avoid the curly braces of the object being interpreted as a statement block:
let todos = ['Buy milk', 'Mow lawn'];
// Below line of code won't work - looks like a statement block
// let todoObjects = todos.map(todo => {todo: todo, done: false});
// Wrap the implicit returned object in parens
let todoObjects = todos.map((todo) => ({todo: todo, done: false}));All arrow functions are expressions. There's no such thing as an arrow function definition/declaration.
// Nope, syntax error (no declarations for arrow functions)
add(x, y) => x + y;
// This is what you want - a function expression
const add = (x, y) => x + y;Arrow functions do not have an arguments "array-like" object:
function checkArgs() { console.log(arguments); }
checkArgs(1, 'abc') // outputs [1, "abc"]
const checkArgs = () => console.log(arguments);
checkArgs(1, 'abc') // outputs Uncaught ReferenceError: arguments is not definedthis Keyword Binding
this in an arrow function is always set to the same context value as its enclosing function (or the global object if not within a function).
const userRoom = {
users: [],
loadUsers: function() {
fetch('https://jsonplaceholder.typicode.com/users')
.then((res) => res.json())
// below will work
.then((users) => {
this.users = users;
});
// below will not work
// .then(function(users) {
// this.users = users;
// });
}
};Due to security policy, test the above code in a tab browsed to https://jsonplaceholder.typicode.com/.
Note that it's not possible to explicitly set this in an arrow-function using the call, apply or bind methods.
Because of the binding rules of this in arrow functions, do not use arrow functions for:
-
Methods in objects that need to access other properties within the object.
For example, this works as expected:
const ticket = { airlines: 'Air SEI', flight: '0116', seat: 'C19', print: function() { console.log(`${this.airlines}: flight ${this.flight} / seat ${this.seat}`); } }But the following doesn't because
thiswithin theprintmethod is bound to window or undefined (in strict mode):const ticket = { airlines: 'Air SEI', flight: '0116', seat: 'C19', print: () => { console.log(`${this.airlines}: flight ${this.flight} / seat ${this.seat}`); } } - Constructor functions also are not a use case for arrow functions because they do not allow JS to set
thisto the shiny new object being created.