JS .includes() vs .some()
JavaScript array is a powerful data structure in web technologies. Methods such as .map()
, .filter(), .includes(),
and .reduce()
helps a lot to overcome issues facing day to day (Checkout my previous article on these 3 methods). However, there are two similar but different methods that are part of your arsenal. In this article we will look in to the methods .includes()
and .some()
to differentiate them, to understand there different usages and applications.
The problem domain
We have a simple array of numbers. We need to check if the number 15
already exists in the list:
Nothing exceptional here, except for the use of the ECMAScript 5(ES5) that can be replaced by a for of/for in
or a while
loop. However, we can greatly simplify the code by using a feature introduced in ECMAScript 7(ES7).
The .includes() method
In ES7 the method has been introduced .includes()
. Let's look at the previous code and then refactor it to use in the new function:
Refactoring is altering the structure of code without changing its final behavior.
The method .includes()
returns true
only if the element exists inside the array. Much leaner, yeah? But, this simplicity can lead to a developer error.
Unexpected Result
Let’s repeat the previous search example with .includes()
, but this time searching an array of objects representing albums:
As much as the function .includes()
worked in the previous example, it seems unable to find our album. What is the reason for this mischievous behavior?
Comparisons between types
Internally, it .includes()
makes a comparison through ===
. However, comparisons with ===
or==
only work as expected (compare value) with the types:
- Boolean
- Null
- Undefined
- Number
- String
- Symbol (ES2015)
When we compare variables that reference the type object
, the interpreter will test whether they point to the same object in memory. Let's look at this simple example:
However, the result will be true if we do something like this:
In this context, we can .includes()
return true
as follows:
As much as this solution works, it makes no sense to use it when searching for an object that we do not know its position, let alone if it exists. In this situation we can turn to the good old .some()
ES5 method.
Using the method .some()
Let’s look at the previous example using the method .some()
:
The function .some()
iterates through each an every element of the array by applying comparison logic. It will abort the iteration immediately as soon as it finds the first item that returns true
during the comparison. The return will be true
if there is any element that satisfies the logic .
The criterion used to compare the id
of the object. Because the property stores a number, comparisons with ==
or ===
use the primitive value and not the reference.
We can still compare all properties of the object with the following trick:
Through JSON.stringify
converts the JavaScript object into a string that is nothing more than the textual representation of the object. Being a representation through one string
, we can use ===
or ==
that the comparison will use the string representation.
One of the great advantages of .some()
is being able to define a more refined comparison logic.
Conclusion
Modern features do not always solve everyday problems that developers face. It is important to know the problem and also the resource used to solve it so we have no surprises or mischievous behaviors as above.
Is that you? Have you ever been surprised by .includes()
? Have you ever used it .some()
to solve a problem? Leave your comment below.