Finding an element
Remember the row of numbered left-luggage lockers. As long as you know the locker number, it is quick: you walk up and open the right one. But sometimes it is the other way round: you remember what the bag looks like but have forgotten the number. Then all you can do is walk along the row and open the lockers in turn until yours turns up.
The splice method cuts elements by their index. But the index of the element you need is often unknown: only the value is known, for example the color "green". An array has two methods for this kind of search, indexOf and includes:
const colors = ["red", "green", "red"];
console.log(colors.indexOf("red")); // 0
console.log(colors.indexOf("blue")); // -1
console.log(colors.includes("green")); // true
console.log(colors.includes("blue")); // falseLet's go through it line by line:
colors.indexOf("red")prints0: the search goes from left to right and stops at the first match.- The method does not notice the second
"red"at the index2. colors.indexOf("blue")prints-1: there is no such element.colors.includes("green")printstrue, and for"blue"it printsfalse.
Two search methods
Both methods walk through the array the way you walked along the lockers: from the index 0 to the end. They differ in what they return.
indexOf
The indexOf method answers the question "where is it?". It returns the index of the first match, or -1 if the element is not there. The number -1 is chosen because an array never has such an index.
Use indexOf when you need the index afterwards: to read the neighboring element or to cut the one you found.
includes
The includes method answers the question "is it there?". It returns true or false, which makes it handy to put straight into an if condition. For example, if (cart.includes("milk")) reads almost like the phrase "if the cart has milk".
Use includes when the element's place does not matter and only the fact itself does.
How they compare
This is where the luggage-locker analogy stops working. You would recognize your bag even in someone else's cover, but the methods compare strictly. Both compare without type conversion, like ===:
console.log([1, 2].indexOf("1")); // -1
console.log([1, 2].includes("1")); // false
console.log([NaN].indexOf(NaN)); // -1
console.log([NaN].includes(NaN)); // trueThe string "1" is not equal to the number 1, so it is not found among numbers. But the methods differ on NaN:
indexOfcompares with===, andNaN === NaNisfalse, soNaNis never found;includesmakes an exception forNaNand finds it.
Interviewers often ask how indexOf differs from includes. The short answer: indexOf returns an index or -1, includes returns true or false, and only includes finds NaN.
Find and cut
Now let's join searching with splice. To remove "green", we first find its index and then cut one element:
const i = colors.indexOf("green");
if (i !== -1) {
colors.splice(i, 1);
}
console.log(colors.join(" ")); // red redThe check i !== -1 is required here. Without it, a missing element would lead to the call splice(-1, 1). And here too, a negative index counts from the end, so the last element would be cut.
Common mistake
The result of indexOf is put straight into a condition:
const colors = ["red", "green"];
if (colors.indexOf("red")) { // ✗
console.log("found");
}There is no error, but the program prints nothing. The element "red" stands first, so indexOf returns 0, and 0 is a falsy value. Yet for a missing element, -1 is a truthy value, and the condition would fire.
To check whether an element is there, write colors.includes("red") or colors.indexOf("red") !== -1.
Key points
indexOfreturns the index of the first match or-1, andincludesreturnstrueorfalse.- Both compare like
===, but onlyincludesfindsNaN. - Before
splice(i, 1), checki !== -1: otherwise the last element gets cut. - The result of
indexOfdoes not go into anifon its own: the index0is a falsy value.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.