How to check if an array contains a value in JavaScript
Checking whether an array contains a specific value is fundamental for validation, conditional logic, and user interface states in modern JavaScript applications.
With over 25 years of experience in software development and as the creator of CoreUI, I have implemented this check thousands of times in components like permission systems, feature toggles, and form validation where specific values determine application behavior.
From my extensive expertise, the most modern and efficient solution is using the includes() method, which provides a clean boolean return value.
This approach is readable, performant, and specifically designed for membership testing in arrays of primitive values.
Use the includes() method to check if an array contains a specific value.
const fruits = ['apple', 'banana', 'orange']
const hasApple = fruits.includes('apple')
// Result: true
The includes() method searches through the array and returns true if the specified value is found, or false if it is not. In this example, fruits.includes('apple') returns true because 'apple' exists in the array. The method uses strict equality (===) for comparison, so it works reliably with primitive values like strings, numbers, and booleans.
1. Checking for Strings
The most common use case for includes() is checking whether a string value exists in an array. This is especially useful for validating user input against a list of allowed values or determining which UI elements to render.
const allowedRoles = ['admin', 'editor', 'moderator']
const userRole = 'editor'
if (allowedRoles.includes(userRole)) {
console.log('Access granted')
} else {
console.log('Access denied')
}
// Result: 'Access granted'
This pattern is ideal for permission checks. Instead of writing a chain of if statements comparing against each allowed value, you store the valid options in an array and let includes() handle the lookup. In CoreUI dashboard templates, we use this exact approach to determine which navigation items to display based on the authenticated user’s role.
2. Checking for Numbers
The includes() method works with all primitive types, including numbers. Because it uses strict equality, there is no risk of type coercion issues that can occur with loose comparisons.
const validPorts = [80, 443, 3000, 8080]
const requestedPort = 443
const isValid = validPorts.includes(requestedPort)
console.log(isValid)
// Result: true
// Strict equality means no type coercion
const stringPort = '443'
console.log(validPorts.includes(stringPort))
// Result: false (string '443' !== number 443)
The strict equality behavior is a significant advantage over older approaches like indexOf(). In this example, the string '443' correctly returns false because it does not match the number 443. This prevents subtle bugs in configuration validation where values might arrive as different types from user input or environment variables.
3. Searching from a Specific Index
The includes() method accepts an optional second argument that specifies the index at which to begin searching. This is useful when you want to skip the beginning of an array or check for duplicate values after a known position.
const letters = ['a', 'b', 'c', 'd', 'a', 'e']
// Search from the beginning (default)
console.log(letters.includes('a'))
// Result: true
// Search starting from index 2
console.log(letters.includes('a', 2))
// Result: true (found at index 4)
// Search starting from index 5
console.log(letters.includes('a', 5))
// Result: false (no 'a' at index 5 or later)
The fromIndex parameter tells the method to start its search at that position and continue to the end of the array. If the index is greater than or equal to the array length, the method returns false without searching. Negative values are also supported and count back from the end of the array, so letters.includes('a', -2) starts searching from the second-to-last element.
4. Case-Insensitive String Checks
Since includes() uses strict equality, string comparisons are case-sensitive by default. To perform a case-insensitive check, you need to normalize both the array values and the search term to the same case before comparing.
const supportedBrowsers = ['Chrome', 'Firefox', 'Safari', 'Edge']
const userBrowser = 'chrome'
// Direct check fails due to case mismatch
console.log(supportedBrowsers.includes(userBrowser))
// Result: false
// Normalize both sides to lowercase
const isSupported = supportedBrowsers
.map((browser) => browser.toLowerCase())
.includes(userBrowser.toLowerCase())
console.log(isSupported)
// Result: true
This approach converts the entire array to lowercase using map() and then checks for the lowercase version of the search term. If you perform this check frequently, consider storing a pre-normalized version of the array to avoid recreating it on every call. This is particularly relevant in CoreUI components that handle user agent detection or feature support checks where casing is unpredictable.
5. Checking for Objects with some()
The includes() method cannot find objects in an array because it compares by reference, not by value. Two objects with identical properties are still different references. For object arrays, use the some() method with a custom comparison function instead.
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
]
// includes() won't work for objects
console.log(users.includes({ id: 2, name: 'Bob' }))
// Result: false (different object reference)
// Use some() to check by property value
const hasUser = users.some((user) => user.id === 2)
console.log(hasUser)
// Result: true
// Check by multiple properties
const hasAdmin = users.some(
(user) => user.name === 'Alice' && user.id === 1
)
console.log(hasAdmin)
// Result: true
The some() method iterates through the array and returns true as soon as the callback returns true for any element, making it efficient because it stops early. This is the standard pattern for membership testing in arrays of objects and is used extensively in CoreUI data table components to check row selection state and highlight active items.
6. Using includes() in Conditional Rendering
A practical application of includes() is controlling which elements appear in a user interface. By maintaining an array of active states or selected items, you can write clean conditional logic without long chains of comparisons.
const activeFeatures = ['dark-mode', 'notifications', 'analytics']
function buildDashboardConfig(features) {
const config = {
showNotifications: features.includes('notifications'),
showAnalytics: features.includes('analytics'),
enableDarkMode: features.includes('dark-mode'),
showBetaTools: features.includes('beta-tools')
}
return config
}
const dashboard = buildDashboardConfig(activeFeatures)
console.log(dashboard)
// Result: {
// showNotifications: true,
// showAnalytics: true,
// enableDarkMode: true,
// showBetaTools: false
// }
Each property in the configuration object is derived from a single includes() call, making the code easy to read and extend. Adding a new feature flag is as simple as adding another property line. This pattern scales well and avoids deeply nested conditional logic that becomes difficult to maintain as your application grows.
Best Practice Note:
The includes() method is supported in all modern browsers and provides better readability than the older indexOf() !== -1 pattern. For large arrays where performance is critical, consider using a Set instead, as Set.has() provides O(1) lookup time compared to the O(n) linear scan of includes(). This is the same approach we use in CoreUI components for permission checks and feature detection. For related operations, see how to find the index of an element, how to filter arrays, and how to remove specific items.



