Array.prototype.includes()

The reason it exists: indexOf uses strict equality and therefore can never find NaN. includes uses SameValueZero and can.

Array methodES2016Live demo
Common call
items.includes(value)
Returns
boolean — no index, no -1 check
Replaces
indexOf(x) !== -1
Watch out
no type coercion — includes("2") is false for [2]
array.includes(searchElement[, fromIndex])
→ boolean

Demo

Live evaluation
Try:
Inputs
itemsnumber[]numbers, comma separated
valuenumbervalue to look for
Output
[1, 2, 3].includes(2)
true

A plain boolean answer — no index to interpret and no -1 to remember. An empty array is always false. The interesting behaviour is not visible with numbers from a text box: includes compares with SameValueZero, which behaves exactly like === except that it considers NaN equal to itself. That one difference is the entire reason the method was added.

Parameters

NameTypeRequiredDescription
searchElementanyyesValue to look for. Compared with SameValueZero: like ===, except NaN equals NaN.
fromIndexnumberno (0)Index to start from. Negative counts from the end.

Return value

boolean — True if the array contains the value, compared with SameValueZero — which treats NaN as equal to itself.

Common patterns

Membership test
The readable replacement for an indexOf comparison.
if (allowed.includes(role)) { ... }
Find NaN
The one thing indexOf cannot do.
if (values.includes(NaN)) { ... }
Guard against a long or-chain
Clearer than repeated equality checks.
if (['a', 'b', 'c'].includes(key)) { ... }

Examples

1. Present
[1, 2, 3].includes(2)
Returns
true
2. Absent
[1, 2, 3].includes(99)
Returns
false
3. Finds NaN
[NaN].includes(NaN)
Returns
true
4. indexOf cannot
[NaN].indexOf(NaN)
Returns
-1
5. No coercion
[1, 2, 3].includes('2')
Returns
false
6. Finds holes
[1, , 3].includes(undefined)
Returns
true

Pitfalls

1. No type coercion
Comparison is strict, so a numeric string never matches a number. Data arriving from a form or a query string routinely fails this way.
String vs number
[1, 2, 3].includes('2')
false
Convert first
[1, 2, 3].includes(Number("2"))
true
2. Objects match by identity, not contents
Two structurally identical objects are different values, so includes says false. Only the very same reference is found.
Different objects
[{id: 1}].includes({id: 1})
false
Use some
[{id: 1}].some(o => o.id === 1)
true
3. ES2016 and newer only
Missing in older runtimes and Internet Explorer entirely. The pre-2016 idiom is an indexOf comparison, which behaves identically apart from NaN.
Missing method
items.includes(x)
TypeError: items.includes is not a function
Old idiom
items.indexOf(x) !== -1
works everywhere

When to use

Use it
  • A plain yes/no membership test
  • Checking a value against a fixed allow-list
  • Any search where NaN might be the value
Reach for something else
  • You need the POSITION → indexOf
  • Matching objects by contents → some with a predicate
  • Large arrays searched repeatedly → a Set, which is O(1)

Notes

Complexity
O(n) — a linear scan, stopping at the first match
Return
A boolean; the array is never modified
CPython impl
V8: Builtins-array-includes.tq
Memory
No allocation
Thread-safe
Single-threaded; the source is only read

FAQ

It reads as the question you are asking and returns a boolean, so there is no -1 to remember. It also finds NaN, which indexOf structurally cannot because it compares with strict equality and NaN !== NaN.

[NaN].includes(NaN)   // true
[NaN].indexOf(NaN)    // -1

History

ES2016
Added specifically to provide a membership test that handles NaN correctly.