Understanding Arrow Functions in JavaScript

Hero image for Understanding Arrow Functions in JavaScript. Image by marianne bos.
Hero image for 'Understanding Arrow Functions in JavaScript.' Image by marianne bos.

JavaScript is a versatile programming language that supports various types of functions. With the introduction of ES6, arrow functions are one of the newer additions to the language that have become increasingly popular due to their conciseness and readability.

In this article, I would like to explore what arrow functions are in JavaScript, how they differ from traditional functions, and when (and how) to use them.


What are Arrow Functions?

Arrow functions, also known as "fat arrow" functions, were introduced in ECMAScript 6 (ES6) as a new syntax for creating functions in JavaScript. They are a shorthand way of defining anonymous functions in JavaScript and tend to be more readable and concise for defining function expressions than more traditional counterparts.

The basic syntax for creating an arrow function looks like this:

const sum = (a, b) => {  return a + b;};

In the example above we've created an arrow function called sum which accepts two parameters (a and b) and returns their sum. The arrow function is defined using the => syntax, which comes after the function's parameter list. The function's body is enclosed in curly braces {...} and contains a return statement which returns the result of the sum operation.

In this instance, this can be made even more concise by removing the braces altogether, although that isn't necessary if you feel it impedes on readability for your developers:

const sum = (a, b) => a + b;

Arrow Functions vs. Traditional Functions

There are a few differences between arrow functions and traditional functions (outside of the obvious syntactical differences).

The this keyword

One of the most significant differences is the way they handle the this keyword.

In traditional functions, the value of this is determined by how the function is called. If the function is called as a method of an object, this refers to the object itself. However, if the function is called as a standalone function, this refers to the global object (which would be window in a browser environment).

On the other hand, arrow functions bind the value of this lexically. That is to say that the value of this inside an arrow function is determined by the surrounding context in which the function is defined; this inside an arrow function always refers to the value of this in the enclosing scope.

That's a lot of words that don't do a great job of describing the nuances at play, so here is an example that hopefully demonstrates the difference between traditional functions and arrow functions when it comes to the this keyword:

const obj = {  name: 'Brian',  sayHello: function () {    console.log(`Hello, ${this.name}!`);  },  sayHelloArrow: () => {    console.log(`Hello, ${this.name}!`);  },};console.log(obj.sayHello());//=> 'Hello, Brian!'obj.sayHelloArrow();//=> 'Hello, undefined!'

In the above example, we have an object obj with two methods: sayHello and sayHelloArrow. sayHello is a traditional function that uses the this keyword to access the name property of the obj object. sayHelloArrow on the other hand is an arrow function, which means that it uses the this keyword to access the name property of the enclosing scope, which is the global object in this case, and hasn't been defined.

When we call obj.sayHello(), the value of this inside the function refers to the obj object and we get the expected output. However, when we call obj.sayHelloArrow(), the value of this inside the function refers to the global object, and we get undefined as the output since name is not defined on the global object.

The arguments object

Another difference between arrow functions and traditional functions is the way they handle the arguments object. In traditional functions, the arguments object is an arraylike object that contains all the arguments passed to the function. Arrow functions do not have their arguments object. Instead, you can use the rest parameter syntax to collect all the arguments into an array.

For example:

const sum = (...args) => {  return args.reduce((acc, curr) => acc + curr, 0);};console.log(sum(1, 2, 3, 4));//=> 10

In the above example, we have defined an arrow function called sum which uses the rest parameter syntax (...args) to collect all the arguments passed to the function into an array. We then use the reduce method to add up all the values in the array together and return the result.


When to Use Arrow Functions

Arrow functions are a great choice for creating small, concise functions that do not require their this keyword or the arguments object. They are particularly useful when working with array methods like map, filter, and reduce.

Here are a few examples that demonstrate using arrow functions with array methods:

const numbers = [1, 2, 3, 4, 5];// using map method with arrow functionconst squaredNumbers = numbers.map(num => num ** 2);console.log(squaredNumbers);  //=> [1, 4, 9, 16, 25]// using filter method with arrow functionconst evenNumbers = numbers.filter(num => num % 2 === 0);console.log(evenNumbers);  //=> [2, 4]// using reduce method with arrow functionconst sumOfNumbers = numbers.reduce((acc, curr) => acc + curr, 0);console.log(sumOfNumbers);  //=> 15

In the above examples, we have an array of numbers numbers and we use arrow functions with the map, filter, and reduce methods to perform various operations on the array. The arrow functions used in this example are concise and readable, making the code more maintainable.


Wrapping‑Up

Arrow functions provide a more concise and readable syntax for creating functions in JavaScript. They differ from traditional functions in how they handle the this keyword and the arguments object. Arrow functions are a great choice for creating small, concise functions that do not require the use of the this keyword or the arguments object and are particularly useful when working with array methods like map, filter, and reduce.


Categories:

  1. ES6
  2. Front‑End Development
  3. JavaScript