Arrow function: forEach, $.each, each

In the previous article, we saw what arrow function is and how it can provide programmers with a more succinct, intuitive way to define a function.

In this article and those that follow, we are going to examine potential pitfalls that we should be aware of when using arrow functions. Specifically, we will focus on what thisrefers to within an arrow/non-arrow function in the context of list processing and event handlers, which are indispensable aspects of all web applications.

We will also learn about how to make sense of this in those different contexts and eliminate any confusions that we might have in terms of this so the process of dealing with this, both in arrow and non-arrow functions, becomes less stressful and more comfortable.

This article will centre around different behaviours of this within the three methods we use all the time for list processing: forEach , $.each , and .each.

These “these” should not get in the way of you using arrow functions

Example code

We will use a small program to see how the value of thischanges when it appears in each of the, um, “each” methods. You can view the code hosted on CodePen here to follow along. You can also copy and paste this HTML file and test the code on your local computer.

The overall structure of the application is as follows.

The application consists of 3 links. When clicked, each link will display a div section that gives us a visual indication of what this refers to within the callback function for forEach , $.each , or .each . Within these 3 methods, we are comparing this with 3 values: currentElement , which is an element a method is currently iterating on; window , which is the window object that is located at the top of the DOM hierarchy; and App , which is an object that contains all the application logic (Note that thiswithin the $.eachand each methods actually refers to the corresponding DOM element and we have to expose the actual value contained within this to compare it with currentElement . The source code used the valueOf method for this purpose. Also notice that the program wraps the array object arraround the jQuery function ($) to be used with the.eachmethod; the method can be called only on jQuery objects).

Result

For those of you who are too busy, lazy, impatient etc., to test the code, which I totally understand as I tend to be one of those people, here is how the value of this changes within the forEach , $.each , and each methods as shown by the program.

Fig1. “this” within the “function” function and the arrow function for the “forEach” method
Fig2. “this” within the “function” function and the arrow function for the $.each” method
Fig3. “this” within the “function” function and the arrow function for the “each” method

You might notice that this within an arrow function always points to the same object, App , regardless of the method the arrow function is used in. If we recall that this within an arrow function is defined within a “lexical scope”, this should make sense, since the value of thisis based on where this can be found in the source code and therefore is sort of already “fixed” once the source code is written. This is one of the reasons we should definitely welcome the creation of the arrow function with open arms; we no longer have to spend our time and energy implementing “clever” techniques, such as bind and call, to deal with context changes and losses.

Tradeoff

As a programmer, it’s important to pay attention to details so we can correctly use our newly found tools.

Firstly, we have to remember that the primary goal of list processing is, as its name suggests, process a list. For this reason, we need to make sure that we have access to each of the elements contained within the list; after all, what’s the point of iterating over a list of elements if we cannot access what we are iterating over?

We then realise that this within an arrow function doesn’t provide access to each element ( currentElement ) contained within the list. If we look at Fig2 and Fig3 above, we also notice a non-arrow function (i.e. function defined with the function keyword), which itself is used as a callback function to the $.each and each methods, actually has this point to the currently iterated element, which is how the jQuery library implements the behaviour of this and is what we have become used to by making extensive use of $.each and .each during our programming career.

Hélas, this within an arrow function overwrites this default behaviour, referencing the App object as per the location it was originally defined within the source code.

Where is the current element?

The question, then, is to know how to access each element within a list using an arrow function from within the $.eachand .eachmethod without the use of this.

We can achieve this simply by relying on the default parameters of each of these methods, rather than onthis , to access each of the elements.

For the forEach method, we should use the first argument of its callback arrow function to access the current element like so:

Using the first argument to access the current element

For the $.each and each methods, we should use the second argument of its callback, arrow function to access the “value” of the current element, which is actually a Javascript object. Note that the first argument of the callback function is reserved for the index of the currently iterated element. You might want to check the MDN documentations for $.each and each if you are not exactly sure how these methods are implemented.

Using the second argument to access the current element

Of course, we can choose not to use an arrow function for the callback function for either $.eachand .eachand instead turn to the non-arrow function and rely on the default value of thisimplemented by jQuery to reference the value (object) of currently iterated element.

Bottom line

While a concise and intuitive code provided by arrow function is quite powerful and programmer-friendly, we have to make sure this refers to what we should expect it to. For jQuery methods in particular (i.e. $.each and each ), we should be careful when using an arrow function as a callback function since it overwrites the default implementation of this pointing to the currently iterated element (object), a behaviour we usually rely on when using these methods . If you decide to use an arrow function as a callback function for either $.eachor .each, make sure to use its second argument to reference the currently iterated value. If you choose to adopt a non-arrow function as a callback function, you can safely use this to access the object you are currently iterating on within these methods.


As always, any suggestions on how the article can be improved (e.g. better example code, bugs, errors, typos, etc) will be greatly appreciated!