Arrow functions(also known as 'fat arrow functions') are a more concise syntax for writing function expressions. Introduced in ES6, arrow functions are definitely one of the most impactful changes in Javascript. These function expressions make your code more readable, and more modern.
Visually, it’s a simple and welcome change, which allows you to write functions with a shorter syntax.
Before es6 we declared a function like this:
function printName(name) {
console.log('Hello' + name)
}
printName('Joe'); // Hello Joe
with es6:
const printName = (name) => {
return ('Hi' + name)
}
console.log(printName('Joe')); // Hi Joe
Implicit return
If the function body contains just a single statement, you can omit the brackets and the return statement:
const printName = (name) => 'Hi' + name
console.log(printName('Joe')); // Hi Joe
If you have one (and just one) parameter, you could omit the parentheses completely:
const printName = name => 'Hi' + name
console.log(printName('Joe')); // Hi Joe
When returning an object, remember to wrap the curly brackets in parentheses to avoid it being considered the wrapping function body brackets:
const myFunction = () => ({ value: 'test' });
myFunction() //{value: 'test'}
this in arrow functions
This is a concept that can be complicated to grasp, as it varies a lot depending on the context and also varies depending on the mode of JavaScript (strict mode or not).
It’s important to clarify this concept because arrow functions behave very differently compared to regular functions.
When defined as a method of an object, in a regular function this refers to the object, so you can do:
const car = {
model: 'Fiesta',
manufacturer: 'Ford',
fullName: function() {
return `${this.manufacturer} ${this.model}`
}
}
calling car.fullName() will return "Ford Fiesta".
This scope with arrow functions is lexically scoped. it inherits from the execution context. An arrow function does not bind this at all, so its value will be looked up in the call stack, so in this code car.fullName() will not work, and will return the string "undefined undefined":
const car = {
model: 'Fiesta',
manufacturer: 'Ford',
fullName: () => {
return `${this.manufacturer} ${this.model}`
}
}
Due to this, arrow functions are not suited as object methods.
Arrow functions cannot be used as constructors either when instantiating an object will raise a TypeError.
This is where regular functions should be used instead when dynamic context is not needed.
This is also a problem when handling events. DOM Event listeners set this to be the target element, and if you rely on this in an event handler, a regular function is necessary:
const link = document.querySelector('#link')
link.addEventListener('click', () => {
// this === window
})
const link = document.querySelector('#link')
link.addEventListener('click', function() {
// this === link
})