Array.prototype.includes()

Determines whether an array contains a given value, returning true or false.

Signature
includes(searchElement)
includes(searchElement, fromIndex)
  • Added in JavaScript ES2016

Parameters

ParameterTypeDescription
$searchElementanyThe value to search for, compared using the SameValueZero algorithm.
$fromIndexoptionalinteger= 0Zero-based index to start searching at, converted to an integer. A negative value counts back from the end (fromIndex + array.length); below -array.length it is treated as 0. If it is at least array.length the array is not searched and false is returned.

Return value

booleantrue if searchElement is found within the array (or within the portion starting at fromIndex), otherwise false.

includes() is the readable membership test: it returns a boolean, so there is no -1 sentinel to remember. Prefer it over indexOf(x) !== -1 whenever you only care whether the value is present.

SameValueZero, not ===

Comparison uses SameValueZero, which behaves like === with exactly one difference: NaN equals itself. (It also treats +0 and -0 as equal, but so does === — that is where SameValueZero differs from Object.is(), not from ===.) The NaN difference is the whole reason to prefer it for numeric data — [NaN].includes(NaN) is true while indexOf() can never find NaN.

What trips people up

It is still an identity check for objects. [{id: 1}].includes({id: 1}) is false, because those are two different objects. Use find() or some() with a predicate to match on contents.

There is no type coercion either: ["1"].includes(1) is false. Normalise types before searching mixed data.

Finally, a negative fromIndex shifts the start of the search but does not reverse it — the array is always scanned front to back from that computed offset.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Check whether a user's role list contains a required permission
  • Test whether a file extension is on an allow-list
  • Detect NaN in a numeric column, which indexOf() cannot do
  • Guard against re-adding a value that is already in a list

Frequently asked questions

What is the difference between includes() and indexOf()?

includes() returns a boolean and finds NaN; indexOf() returns a position and uses strict equality, so it can never locate NaN. Use includes() for a yes/no test and indexOf() when you need the index.

Why does includes() return false for an object that looks identical?

Because it compares references, not structure. Two object literals with the same properties are distinct values — use arr.some(o => o.id === target.id) to match on contents.

Is includes() case-sensitive for strings?

Yes — string elements are compared exactly, so ['Admin'].includes('admin') is false. Normalise the case first with map(s => s.toLowerCase()), or use some() with a case-insensitive comparison.

More examples

How fromIndex behaves

Prints false, true, true, false. Starting at index 1 skips past the only 'a'. -1 resolves to index 2 and still scans forward, finding 'c'. A fromIndex below -length is clamped to 0, so the whole array is searched; one past the end short-circuits to false.

Example · javascript
const letters = ["a", "b", "c"];

console.log(letters.includes("a", 1));
console.log(letters.includes("c", -1));
console.log(letters.includes("a", -100));
console.log(letters.includes("c", 5));

Reference identity and no coercion

Prints false, true, true, false, true. A fresh object literal is never the same reference, so some() with a predicate is the right tool for structural matching. The string '1' does not match the number 1, and SameValueZero treats -0 and 0 as equal.

Example · javascript
const objs = [{ id: 1 }];

console.log(objs.includes({ id: 1 }));
console.log(objs.includes(objs[0]));
console.log(objs.some((o) => o.id === 1));
console.log(["1", "2"].includes(1));
console.log([-0].includes(0));

Discussion

  • Be the first to comment on this lesson.