includes
Sometimes you do not need to transform, filter, sort, or flatten an array.
Sometimes you only need to ask a simple question:
Does this array contain this value?That is what .includes() is for.
What Is includes?
includes checks whether an array contains a specific value.
It returns a boolean:
truefalse
const roles = ["admin", "editor", "viewer"];
console.log(roles.includes("admin")); // true
console.log(roles.includes("guest")); // falseincludes is simple, readable, and useful for checking membership.
Basic Syntax
array.includes(valueToFind);Example:
const fruits = ["Apple", "Banana", "Cherry"];
const hasBanana = fruits.includes("Banana");
console.log(hasBanana); // trueThe value must match an element in the array.
If no element matches, the result is false.
Checking Strings in an Array
const allowedRoles = ["admin", "editor"];
const userRole = "editor";
if (allowedRoles.includes(userRole)) {
console.log("Access granted");
} else {
console.log("Access denied");
}Output:
Access grantedThis is a common use case.
Instead of writing:
if (userRole === "admin" || userRole === "editor") {
console.log("Access granted");
}You can write:
if (allowedRoles.includes(userRole)) {
console.log("Access granted");
}This becomes easier to read as the list grows.
Checking Numbers in an Array
const selectedIds = [101, 204, 309];
console.log(selectedIds.includes(204)); // true
console.log(selectedIds.includes(999)); // falseThis is useful when checking selected values, allowed IDs, or completed steps.
Checking Booleans
includes works with booleans too.
const validationResults = [true, true, false];
console.log(validationResults.includes(false)); // trueThis tells you at least one validation failed.
However, for this kind of boolean test, .some() or .every() may communicate intent better:
const allValid = validationResults.every((result) => result === true);
console.log(allValid); // falseUse the method that makes the question clearest.
includes Is Case-Sensitive
String checks are case-sensitive.
const fruits = ["Apple", "Banana", "Cherry"];
console.log(fruits.includes("Apple")); // true
console.log(fruits.includes("apple")); // falseIf you want a case-insensitive check, normalize the values.
const fruits = ["Apple", "Banana", "Cherry"];
const search = "apple";
const hasFruit = fruits
.map((fruit) => fruit.toLowerCase())
.includes(search.toLowerCase());
console.log(hasFruit); // trueFor larger arrays, you may prefer .some() to avoid creating a new array:
const hasFruit = fruits.some((fruit) => {
return fruit.toLowerCase() === search.toLowerCase();
});
console.log(hasFruit); // trueUsing fromIndex
includes has an optional second argument:
array.includes(valueToFind, fromIndex);fromIndex tells JavaScript where to start searching.
const letters = ["A", "B", "C", "B"];
console.log(letters.includes("B")); // true
console.log(letters.includes("B", 2)); // true
console.log(letters.includes("B", 3)); // true
console.log(letters.includes("B", 4)); // falseThe last check starts at index 4.
There is no item at index 4, so it returns false.
Negative fromIndex
fromIndex can be negative.
A negative value starts searching that many positions from the end.
const letters = ["A", "B", "C", "D"];
console.log(letters.includes("C", -2)); // true
console.log(letters.includes("B", -2)); // false-2 starts searching from index 2, which is "C".
So "C" is found, but "B" is not searched.
Most of the time, you will use includes without fromIndex.
But it is useful to know it exists.
includes and NaN
includes can find NaN.
const values = [1, 2, NaN, 4];
console.log(values.includes(NaN)); // trueThis is helpful because NaN is unusual:
console.log(NaN === NaN); // falseEven though NaN === NaN is false, includes(NaN) works.
includes With Objects
This is an important reference-type caveat.
includes checks whether the array contains the exact same object reference.
const user = { id: 1, name: "Alice" };
const users = [user];
console.log(users.includes(user)); // trueThis works because the same object reference is in the array.
But this does not work:
const users = [{ id: 1, name: "Alice" }];
console.log(users.includes({ id: 1, name: "Alice" })); // falseThe object looks the same, but it is a different object in memory.
Objects are compared by reference, not by shape.
Finding Objects by Property
If you need to check whether an object with a certain property exists, use .some() or .find().
Use .some() when you need a boolean:
const users = [{ id: 1, name: "Alice" }];
const hasUser = users.some((user) => user.id === 1);
console.log(hasUser); // trueUse .find() when you need the object:
const user = users.find((user) => user.id === 1);
console.log(user); // { id: 1, name: "Alice" }Do not use includes to search object properties.
Use it for direct value membership.
includes vs indexOf
Before includes, developers often used indexOf.
const fruits = ["Apple", "Banana", "Cherry"];
console.log(fruits.indexOf("Banana")); // 1
console.log(fruits.indexOf("Orange")); // -1To check membership with indexOf, you had to write:
if (fruits.indexOf("Banana") !== -1) {
console.log("Found it");
}With includes, the intent is clearer:
if (fruits.includes("Banana")) {
console.log("Found it");
}Use includes when you only need a boolean.
Use indexOf if you specifically need the index of a primitive value.
includes vs some
Both can answer yes/no questions.
Use includes for direct value checks:
const roles = ["admin", "editor"];
console.log(roles.includes("admin")); // trueUse some for condition-based checks:
const users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "user" },
];
const hasAdmin = users.some((user) => user.role === "admin");
console.log(hasAdmin); // trueComparison:
| Method | Best for | Returns |
|---|---|---|
includes |
Checking a direct value | Boolean |
some |
Checking a condition | Boolean |
Practical Example: Feature Flags
const enabledFeatures = ["dark-mode", "notifications", "autosave"];
function isFeatureEnabled(featureName) {
return enabledFeatures.includes(featureName);
}
console.log(isFeatureEnabled("dark-mode")); // true
console.log(isFeatureEnabled("beta-dashboard")); // falseThis pattern is easy to read.
The array stores allowed values.
includes checks whether a requested value exists in that list.
Practical Example: Form Validation
const allowedFileTypes = ["jpg", "png", "webp"];
const uploadedFileType = "png";
if (allowedFileTypes.includes(uploadedFileType)) {
console.log("File type allowed");
} else {
console.log("Invalid file type");
}This is a clean alternative to several || checks.
Practical Example: Avoiding Duplicates
You can use includes before adding a value.
const tags = ["javascript", "arrays"];
const newTag = "javascript";
if (!tags.includes(newTag)) {
tags.push(newTag);
}
console.log(tags); // ["javascript", "arrays"]This prevents duplicate primitive values.
For objects, use a property check with .some() instead.
const users = [{ id: 1, name: "Alice" }];
const newUser = { id: 1, name: "Alice" };
const alreadyExists = users.some((user) => user.id === newUser.id);
if (!alreadyExists) {
users.push(newUser);
}Best Practices
Use includes for simple value membership:
const hasRole = allowedRoles.includes(userRole);Use some for object property checks:
const hasUser = users.some((user) => user.id === targetId);Normalize strings for case-insensitive checks:
const hasName = names.some((name) => {
return name.toLowerCase() === search.toLowerCase();
});Use includes instead of indexOf(...) !== -1 when you only need true or false:
const hasItem = items.includes(item);Remember that includes compares objects by reference:
users.includes({ id: 1 }); // Usually not what you wantCommon Mistakes
Mistake 1: Expecting Object Shape Comparison
const users = [{ id: 1, name: "Alice" }];
console.log(users.includes({ id: 1, name: "Alice" })); // falseThe object has the same properties, but it is not the same reference.
Use some:
const exists = users.some((user) => user.id === 1);
console.log(exists); // trueMistake 2: Forgetting Case Sensitivity
const fruits = ["Apple", "Banana"];
console.log(fruits.includes("apple")); // falseNormalize both sides:
const hasApple = fruits.some((fruit) => {
return fruit.toLowerCase() === "apple";
});
console.log(hasApple); // trueMistake 3: Using includes When You Need the Item
const users = [{ id: 1, name: "Alice" }];
const result = users.includes(1);
console.log(result); // falseThe array contains objects, not the number 1.
Use find if you need the object:
const user = users.find((user) => user.id === 1);Mistake 4: Using includes When You Need All Matches
includes only answers whether a value exists.
It does not return matching items.
Use filter for all matches:
const admins = users.filter((user) => user.role === "admin");Quick Check
What does this return?
const roles = ["admin", "editor", "viewer"];
roles.includes("editor");It returns:
trueWhat does this return?
const fruits = ["Apple", "Banana"];
fruits.includes("apple");It returns:
falseincludes is case-sensitive.
What does this return?
const users = [{ id: 1 }];
users.includes({ id: 1 });It returns:
falseThe object being searched for is a different reference.
Use some for property-based checks:
users.some((user) => user.id === 1);Summary
includes checks whether an array contains a specific value.
- It returns
trueorfalse. - It is best for direct primitive value checks.
- It is case-sensitive for strings.
- It can find
NaN. - It accepts an optional
fromIndex. - It compares objects by reference, not by shape.
- Use
somefor condition-based checks. - Use
findwhen you need the matching item. - Use
filterwhen you need all matching items.