javascript
array

How do I check if an array includes a value in JavaScript?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Checking whether an array contains a value sounds simple, but the right method depends on what "match" means in your code. Sometimes you want exact scalar membership, sometimes you want to search objects by a property, and sometimes performance matters because the lookup happens many times. Modern JavaScript gives you a few clear tools for each case.

Use includes for Simple Value Membership

For arrays of primitive values such as strings, numbers, or booleans, Array.prototype.includes is the clearest choice.

javascript
1const roles = ["user", "admin", "editor"];
2
3console.log(roles.includes("admin")); // true
4console.log(roles.includes("guest")); // false

includes returns a boolean directly, which is usually more readable than checking whether an index is -1.

You can also provide a starting position:

javascript
1const values = [10, 20, 30, 20];
2
3console.log(values.includes(20, 2)); // true
4console.log(values.includes(10, 1)); // false

That is useful when you only want to search from a certain part of the array onward.

Understand How includes Compares Values

includes uses SameValueZero comparison. In practice, that means it behaves like strict equality for most everyday cases, with one important exception: NaN matches NaN.

javascript
console.log([NaN].includes(NaN)); // true
console.log([0].includes(-0));    // true

This difference matters if you are migrating older code from indexOf, because indexOf does not find NaN.

javascript
console.log([NaN].indexOf(NaN)); // -1

Use some for Object Arrays and Custom Logic

If your array contains objects, includes only checks reference identity. Two different objects with the same properties are not considered equal.

javascript
1const a = { id: 1 };
2const b = { id: 1 };
3
4console.log([a].includes(a)); // true
5console.log([a].includes(b)); // false

When the real question is "does any element satisfy this condition," use some.

javascript
1const users = [
2  { id: 1, active: false },
3  { id: 2, active: true },
4];
5
6const hasUserTwo = users.some((user) => user.id === 2);
7const hasActiveUser = users.some((user) => user.active);
8
9console.log(hasUserTwo);    // true
10console.log(hasActiveUser); // true

some is the right tool when matching is based on a property or a computed rule rather than exact value identity.

Use find When You Need the Matching Item

Sometimes you do not just need a yes or no answer. You need the matching object itself. In that case, find is often more useful than some.

javascript
1const products = [
2  { sku: "A-100", price: 25 },
3  { sku: "B-200", price: 40 },
4];
5
6const product = products.find((item) => item.sku === "B-200");
7
8console.log(product);
9console.log(product !== undefined);

If you only check existence, some communicates intent more clearly. If you need the actual element, find avoids searching twice.

Use a Set for Repeated Lookups

Array scans are fine for occasional membership checks, but repeated lookups in large collections can become wasteful. A Set gives you a more appropriate data structure for that case.

javascript
1const blockedWords = ["spam", "scam", "fraud"];
2const blockedSet = new Set(blockedWords);
3
4console.log(blockedSet.has("spam")); // true
5console.log(blockedSet.has("safe")); // false

This is especially useful in validation code, parsers, or other hot paths where you perform many membership checks against the same list.

Normalize Data Before Comparing

Many "membership bugs" are not really about the method. They are about inconsistent data. Case differences and mismatched types are common examples.

javascript
1const tags = ["Apple", "Banana", "Cherry"];
2
3function hasTagIgnoreCase(tagList, candidate) {
4  return tagList
5    .map((tag) => tag.toLowerCase())
6    .includes(candidate.toLowerCase());
7}
8
9console.log(hasTagIgnoreCase(tags, "banana")); // true
10console.log([1, 2, 3].includes("2"));          // false

If the source array contains numbers, compare with numbers. If user input arrives as strings, convert it before checking membership.

Common Pitfalls

The most common pitfall is using includes on an array of objects and expecting it to compare object contents. It compares references, so only the exact same object instance matches.

Another issue is relying on indexOf in new code when includes expresses the intent more clearly. indexOf still works, but it is easier to read the boolean result from includes.

Teams also often ignore normalization rules. Case-sensitive strings and mixed numeric types can make a valid value look absent when the real problem is inconsistent input.

Finally, repeated .includes calls on a large array can become a design issue. At that point, use a Set.

Summary

  • Use includes for straightforward membership checks in arrays of primitive values.
  • Use some when matching depends on a property or custom predicate.
  • Use find when you need the matching element, not just a boolean.
  • Use Set.has for repeated lookups in larger collections.
  • Normalize string case and value types before comparing when business rules require it.

Course illustration
Course illustration

All Rights Reserved.