ES6 (ES2015) and up

If you're using ECMAScript 6 (a.k.a. ES2015) or higher, the cleanest way is to construct an array of the items and use Array.includes:

['a', 'b', 'c'].includes('b')

This has some inherent benefits over indexOf because it can properly test for the presence of NaN in the list, and can match missing array elements such as the middle one in [1, , 2] to undefined. It also treats +0 and -0 as equal. includes also works on JavaScript typed arrays such as Uint8Array.

If you're concerned about browser support (such as for IE or Edge), you can check Array.includes at CanIUse.Com, and if you want to target a browser or browser version that's missing includes, you'll need to transpile to a lower ECMAScript version using a tool such as Babel, or include a polyfill script in the browser, such as those available at polyfill.io.

Higher Performance

Note that there is no guarantee that Array.includes() execution time won't scale with the number of elements in the array: it can have performance O(n). If you need higher performance, and won't be constructing the set of items repeatedly (but will be repeatedly checking if the items contain some element), you should use a Set because the ES spec requires implementations of Set (and Map as well) to be sub-linear for reads:

The specification requires sets to be implemented "that, on average, provide access times that are sublinear on the number of elements in the collection". Therefore, it could be represented internally as a hash table (with O(1) lookup), a search tree (with O(log(N)) lookup), or any other data structure, as long as the complexity is better than O(N).

const interestingItems = new Set(['a', 'b', 'c'])
const isItemInSet = interestingItems.has('b')

Note that you can pass in any iterable item to the Set constructor (anything that supports for...of). You can also convert a Set to an array using Array.from(set) or by spreading it [...set].

Without An Array

This is not really recommended, but you could add a new isInList property to strings as follows:

if (!String.prototype.isInList) {
  Object.defineProperty(String.prototype, 'isInList', {
    get: () => function(...args) {
      let value = this.valueOf();
      for (let i = 0, l = args.length; i < l; i += 1) {
        if (arguments[i] === value) return true;
      }
      return false;
    }
  });
}

Then use it like so:

'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false

You can do the same thing for Number.prototype.

Note that Object.defineProperty cannot be used in IE8 and earlier, or very old versions of other browsers. However, it is a far superior solution to String.prototype.isInList = function() { ... } because using simple assignment like that will create an enumerable property on String.prototype, which is more likely to break code.

Array.indexOf

If you are using a modern browser, indexOf always works. However, for IE8 and earlier you'll need a polyfill.

If indexOf returns -1, the item is not in the list. Be mindful though, that this method will not properly check for NaN, and while it can match an explicit undefined, it can’t match a missing element to undefined as in the array [1, , 2].

Polyfill for indexOf or includes in IE, or any other browser/version lacking support

If you don't want to use a service like polyfill.io as mentioned above, you can always include in your own source code standards-compliant custom polyfills. For example, the CoreJs library has an implementation of indexOf.

In this situation where I had to make a solution for Internet Explorer 7, I "rolled my own" simpler version of the indexOf() function that is not standards-compliant:

if (!Array.prototype.indexOf) {
   Array.prototype.indexOf = function(item) {
      var i = this.length;
      while (i--) {
         if (this[i] === item) return i;
      }
      return -1;
   }
}

Notes On Modifying Object Prototypes

However, I don't think modifying String.prototype or Array.prototype is a good strategy long term. Modifying object prototypes in JavaScript can lead to serious bugs. You need to decide whether doing so is safe in your own environment. Of primary note is that iterating an array (when Array.prototype has added properties) with for ... in will return the new function name as one of the keys:

Array.prototype.blah = function() { console.log('blah'); };
let arr = [1, 2, 3];
for (let x in arr) { console.log(x); }
// Result:
0
1
2
blah // Extra member iterated over!

Your code may work now, but the moment someone in the future adds a third-party JavaScript library or plugin that isn't zealously guarding against inherited keys, everything can break.

The old way to avoid that breakage is, during enumeration, to check each value to see if the object actually has it as a non-inherited property with if (arr.hasOwnProperty(x)) and only then work with that x.

The new ES6 ways to avoid this extra-key problem are:

  1. Use of instead of in, for (let x of arr). However, depending on the output target and the exact settings/capabilities of your down-leveling transpiler, this may not be reliable. Plus, unless you can guarantee that all of your code and third-party libraries strictly stick to this method, then for the purposes of this question you'll probably just want to use includes as stated above.

  2. Define your new properties on the prototype using Object.defineProperty(), as this will make the property (by default) non-enumerable. This only truly solves the problem if all the JavaScript libraries or modules you use also do this.

A Gotcha: Execution Scope in Browsers and Node.js

While browser polyfills make sense, and object prototype modification is a useful strategy, there can be scoping problems in both browsers and Node.js, for their own unique reasons.

In a browser, each distinct document object is its own new global scope, and in browser JS it is possible to create new documents (such as those used for off-screen rendering or to create document fragments) or to get a reference to another page's document object (such as via inter-page communication using a named-target link) so it's possible in certain (rare?) circumstances that object prototypes won't have the methods you expect them to have—though you could always run your polyfills again against the new global objects...

In Node.js, modifying prototypes of global objects may be safe, but modifying the prototypes of non-global, imported objects could lead to breakage if you ever end up with two versions of the same package being required/imported, because imports of the two versions will not expose the same objects, thus won't have the same object prototypes. That is, your code could work fine until a dependency or sub-dependency uses a different version from the one you expect, and without any of your own code changing, a simple npm install or yarn install could trigger this problem. (There are options to deal with this, such as yarn's resolutions property in the package.json, but that's not a good thing to rely on if you have other options.)

This Node.js issue extends beyond version differences and can occur even with the same version used by different imports, because when an app is fully transpiled and run (or code in a package is consumed in another app), different parts of the app can end up importing commonJs code AND ES-module code. Unless packages are very, very carefully designed so that there is a single, cross-module-style commonJs-written core import used in them, then you can get very surprising splits between these two, even if everything works in a test app consuming your package! That's because you can't control the transpilation and down-leveling specifics of apps consuming the package, and your nice and pretty ES module could get down-leveled or cross-module transformed, even after your own transpiling and bundling process during publishing.

Sopecial steps have to be taken to ensure modified Object prototypes have been modified on every use, or other engineering done to ensure that transpilation and bundling don't break things.

Answer from ErikE on Stack Overflow
Top answer
1 of 15
543

ES6 (ES2015) and up

If you're using ECMAScript 6 (a.k.a. ES2015) or higher, the cleanest way is to construct an array of the items and use Array.includes:

['a', 'b', 'c'].includes('b')

This has some inherent benefits over indexOf because it can properly test for the presence of NaN in the list, and can match missing array elements such as the middle one in [1, , 2] to undefined. It also treats +0 and -0 as equal. includes also works on JavaScript typed arrays such as Uint8Array.

If you're concerned about browser support (such as for IE or Edge), you can check Array.includes at CanIUse.Com, and if you want to target a browser or browser version that's missing includes, you'll need to transpile to a lower ECMAScript version using a tool such as Babel, or include a polyfill script in the browser, such as those available at polyfill.io.

Higher Performance

Note that there is no guarantee that Array.includes() execution time won't scale with the number of elements in the array: it can have performance O(n). If you need higher performance, and won't be constructing the set of items repeatedly (but will be repeatedly checking if the items contain some element), you should use a Set because the ES spec requires implementations of Set (and Map as well) to be sub-linear for reads:

The specification requires sets to be implemented "that, on average, provide access times that are sublinear on the number of elements in the collection". Therefore, it could be represented internally as a hash table (with O(1) lookup), a search tree (with O(log(N)) lookup), or any other data structure, as long as the complexity is better than O(N).

const interestingItems = new Set(['a', 'b', 'c'])
const isItemInSet = interestingItems.has('b')

Note that you can pass in any iterable item to the Set constructor (anything that supports for...of). You can also convert a Set to an array using Array.from(set) or by spreading it [...set].

Without An Array

This is not really recommended, but you could add a new isInList property to strings as follows:

if (!String.prototype.isInList) {
  Object.defineProperty(String.prototype, 'isInList', {
    get: () => function(...args) {
      let value = this.valueOf();
      for (let i = 0, l = args.length; i < l; i += 1) {
        if (arguments[i] === value) return true;
      }
      return false;
    }
  });
}

Then use it like so:

'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false

You can do the same thing for Number.prototype.

Note that Object.defineProperty cannot be used in IE8 and earlier, or very old versions of other browsers. However, it is a far superior solution to String.prototype.isInList = function() { ... } because using simple assignment like that will create an enumerable property on String.prototype, which is more likely to break code.

Array.indexOf

If you are using a modern browser, indexOf always works. However, for IE8 and earlier you'll need a polyfill.

If indexOf returns -1, the item is not in the list. Be mindful though, that this method will not properly check for NaN, and while it can match an explicit undefined, it can’t match a missing element to undefined as in the array [1, , 2].

Polyfill for indexOf or includes in IE, or any other browser/version lacking support

If you don't want to use a service like polyfill.io as mentioned above, you can always include in your own source code standards-compliant custom polyfills. For example, the CoreJs library has an implementation of indexOf.

In this situation where I had to make a solution for Internet Explorer 7, I "rolled my own" simpler version of the indexOf() function that is not standards-compliant:

if (!Array.prototype.indexOf) {
   Array.prototype.indexOf = function(item) {
      var i = this.length;
      while (i--) {
         if (this[i] === item) return i;
      }
      return -1;
   }
}

Notes On Modifying Object Prototypes

However, I don't think modifying String.prototype or Array.prototype is a good strategy long term. Modifying object prototypes in JavaScript can lead to serious bugs. You need to decide whether doing so is safe in your own environment. Of primary note is that iterating an array (when Array.prototype has added properties) with for ... in will return the new function name as one of the keys:

Array.prototype.blah = function() { console.log('blah'); };
let arr = [1, 2, 3];
for (let x in arr) { console.log(x); }
// Result:
0
1
2
blah // Extra member iterated over!

Your code may work now, but the moment someone in the future adds a third-party JavaScript library or plugin that isn't zealously guarding against inherited keys, everything can break.

The old way to avoid that breakage is, during enumeration, to check each value to see if the object actually has it as a non-inherited property with if (arr.hasOwnProperty(x)) and only then work with that x.

The new ES6 ways to avoid this extra-key problem are:

  1. Use of instead of in, for (let x of arr). However, depending on the output target and the exact settings/capabilities of your down-leveling transpiler, this may not be reliable. Plus, unless you can guarantee that all of your code and third-party libraries strictly stick to this method, then for the purposes of this question you'll probably just want to use includes as stated above.

  2. Define your new properties on the prototype using Object.defineProperty(), as this will make the property (by default) non-enumerable. This only truly solves the problem if all the JavaScript libraries or modules you use also do this.

A Gotcha: Execution Scope in Browsers and Node.js

While browser polyfills make sense, and object prototype modification is a useful strategy, there can be scoping problems in both browsers and Node.js, for their own unique reasons.

In a browser, each distinct document object is its own new global scope, and in browser JS it is possible to create new documents (such as those used for off-screen rendering or to create document fragments) or to get a reference to another page's document object (such as via inter-page communication using a named-target link) so it's possible in certain (rare?) circumstances that object prototypes won't have the methods you expect them to have—though you could always run your polyfills again against the new global objects...

In Node.js, modifying prototypes of global objects may be safe, but modifying the prototypes of non-global, imported objects could lead to breakage if you ever end up with two versions of the same package being required/imported, because imports of the two versions will not expose the same objects, thus won't have the same object prototypes. That is, your code could work fine until a dependency or sub-dependency uses a different version from the one you expect, and without any of your own code changing, a simple npm install or yarn install could trigger this problem. (There are options to deal with this, such as yarn's resolutions property in the package.json, but that's not a good thing to rely on if you have other options.)

This Node.js issue extends beyond version differences and can occur even with the same version used by different imports, because when an app is fully transpiled and run (or code in a package is consumed in another app), different parts of the app can end up importing commonJs code AND ES-module code. Unless packages are very, very carefully designed so that there is a single, cross-module-style commonJs-written core import used in them, then you can get very surprising splits between these two, even if everything works in a test app consuming your package! That's because you can't control the transpilation and down-leveling specifics of apps consuming the package, and your nice and pretty ES module could get down-leveled or cross-module transformed, even after your own transpiling and bundling process during publishing.

Sopecial steps have to be taken to ensure modified Object prototypes have been modified on every use, or other engineering done to ensure that transpilation and bundling don't break things.

2 of 15
330

You can call indexOf:

if (['a', 'b', 'c'].indexOf(str) >= 0) {
    //do something
}
🌐
Luasoftware
code.luasoftware.com › tutorials › javascript › check-if-string-in-list-with-javascript
Javascript: Check If String In List - Lua Software Code
November 2, 2017 - It's simple using ES6 Javascript. TIPS: you can use Babel (or use babel-loader with Webpack) for cross-browser support. ... Using indexOf, but it doesn't work with IE8. if (['apple', 'orange', 'banana'].indexOf(value) >= 0) { // found}
People also ask

What is the best method to check if a string is in a list in JavaScript for IE7?
A: The most reliable method for IE7 is creating a custom implementation of indexOf() or using a for loop to manually check each string in the list.
🌐
sqlpey.com
sqlpey.com › javascript › top-5-methods-to-check-if-a-string-is-in-a-list-in-javascript
Top 5 Methods to Check if a String is in a List in JavaScript
How does Set improve performance over Array.includes?
A: A Set provides average access times that are sublinear, allowing for faster membership checks compared to an array with methods like includes which can have linear time complexity.
🌐
sqlpey.com
sqlpey.com › javascript › top-5-methods-to-check-if-a-string-is-in-a-list-in-javascript
Top 5 Methods to Check if a String is in a List in JavaScript
Are there risks in modifying built-in prototypes?
A: Yes, modifying prototypes can lead to issues with third-party libraries that may not expect these changes, potentially causing bugs in your application.
🌐
sqlpey.com
sqlpey.com › javascript › top-5-methods-to-check-if-a-string-is-in-a-list-in-javascript
Top 5 Methods to Check if a String is in a List in JavaScript
🌐
sqlpey
sqlpey.com › javascript › top-5-methods-to-check-if-a-string-is-in-a-list-in-javascript
Top 5 Methods to Check if a String is in a List in JavaScript
November 23, 2024 - Be mindful, however, of its limitations with NaN and undefined checks. If you wish to circumvent the need for external libraries like polyfill.io , consider implementing your own simpler polyfill for indexOf(): if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(item) { for (let i = 0; i < this.length; i++) { if (this[i] === item) return i; } return -1; }; } Using modern JavaScript features not only enhances code clarity but also performance.
Top answer
1 of 5
2

You can use following approach in different scenario:

JSON.stringify

If its just about finding availability, you can get JSON string and then check in it.

As correctly pointed by corn3lius, just checking search value will search in keys as well. You can wrap searchValue in ":..." and this will only search in values

Show code snippet

var myList = [{type:'Prospect__c', typeName__c:'high_school', },
{type:'Procedure__c', typeName__c:'in_program', },
{type:'Procedure__c', typeName__c:'attention_plz', }]
var searchVal = 'in_program';

var exist= JSON.stringify(myList).indexOf(":\"" + searchVal + "\"") > -1;

console.log(exist)
Run code snippetEdit code snippet Hide Results Copy to answer Expand

Array.some

An alternate could be using array function if you know the exact key to lookup

Show code snippet

var myList = [{type:'Prospect__c', typeName__c:'high_school', },
{type:'Procedure__c', typeName__c:'in_program', },
{type:'Procedure__c', typeName__c:'attention_plz', }]
var searchVal = 'in_program';

var exist= myList.some(function(o){ return o.typeName__c === searchVal });

console.log(exist)
Run code snippetEdit code snippet Hide Results Copy to answer Expand

Array.find

If you want to find first object where value matches, you should use Array.find

Show code snippet

var myList = [{type:'Prospect__c', typeName__c:'high_school', },
{type:'Procedure__c', typeName__c:'in_program', },
{type:'Procedure__c', typeName__c:'attention_plz', }]
var searchVal = 'in_program';

var exist= myList.find(function(o){ return o.typeName__c === searchVal });

console.log(exist)
Run code snippetEdit code snippet Hide Results Copy to answer Expand

Array.filter

If you want to find all objects where value matches, you should use Array.filter

Show code snippet

var myList = [{type:'Prospect__c', typeName__c:'high_school', },
{type:'Procedure__c', typeName__c:'in_program', },
{type:'Procedure__c', typeName__c:'attention_plz', }]
var searchVal = 'Procedure__c';

var exist= myList.filter(function(o){ return o.type === searchVal });

console.log(exist)
Run code snippetEdit code snippet Hide Results Copy to answer Expand

2 of 5
2

There are a bunch of different strategies you can follow, but indexOf would only work if you were looking for the exact same root object, not one of its properties

A good approach would be with filter:

var filteredItems = myList.filter(function(a) { 
  return a.typeName__c === 'in_program' 
})
console.log(filteredItems.length === 0) // false

This will return a new collection with the items filtered by the returned value of the callback. Then, you check the length and see if it's 0 or greater.

Find elsewhere
🌐
Mimo
mimo.org › glossary › javascript › includes-method
JavaScript includes() method: Syntax, Usage, and Examples
Use includes() to instantly check if values exist in strings or arrays—no loops, no complexity. Perfect for validation, filtering, and quick logic.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › String › includes
String.prototype.includes() - JavaScript - MDN Web Docs
const sentence = "The quick brown fox jumps over the lazy dog."; const word = "fox"; console.log( `The word "${word}" ${ sentence.includes(word) ? "is" : "is not" } in the sentence`, ); // Expected output: "The word "fox" is in the sentence" ... A string to be searched for within str.
🌐
javaspring
javaspring.net › blog › determine-if-string-is-in-list-in-javascript
How to Check if a String is in a List in JavaScript: Better Alternatives to SQL's IN Clause — javaspring.net
If you’re familiar with SQL, you’ve likely used the IN clause to check if a value exists within a list of values (e.g., WHERE username IN ('alice', 'bob', 'charlie')). It’s a concise way to perform membership checks, but JavaScript doesn’t have a built-in IN clause for arrays. Instead, JavaScript offers a variety of methods to achieve the same goal—often with more flexibility and better performance than SQL’s IN. In this blog, we’ll explore 6 powerful JavaScript alternatives to SQL’s IN clause for checking if a string exists in a list (array).
🌐
freeCodeCamp
freecodecamp.org › news › check-if-an-item-is-in-an-array-in-javascript-js-contains-with-array-includes
Check if an Item is in an Array in JavaScript – JS Contains with Array.includes()
June 28, 2022 - The substring "web" doesn't exist in the string so false gets returned. In this article, we talked about the includes() method in JavaScript. You use it to check if an item exists in an array.
🌐
xjavascript
xjavascript.com › blog › typescript-check-if-string-in-list
TypeScript: Checking if a String is in a List — xjavascript.com
In TypeScript, a statically typed superset of JavaScript, there are various scenarios where you might need to check if a given string exists within a list. This could be for validation purposes, filtering data, or implementing conditional logic. Understanding how to perform this operation ...
🌐
Webdevtutor
webdevtutor.net › blog › typescript-check-if-string-is-in-list
How to Check if a String is in a List in Typescript
const myList: string[] = ['apple', 'banana', 'orange']; const searchString: string = 'banana'; if (myList.includes(searchString)) { console.log(`${searchString} is in the list.`); } else { console.log(`${searchString} is not in the list.`); } Another approach is to use the Array.some() method, which tests whether at least one element in the array passes the test implemented by the provided function. const myList: string[] = ['apple', 'banana', 'orange']; const searchString: string = 'banana'; if (myList.some(item => item === searchString)) { console.log(`${searchString} is in the list.`); } else { console.log(`${searchString} is not in the list.`); }
🌐
GitHub
gist.github.com › chrisjhoughton › 5554466
See if an array/string contains something. Nothing fancy, but without a library you'll need this as array.indexOf doesn't work in IE8 and lower. · GitHub
See if an array/string contains something. Nothing fancy, but without a library you'll need this as array.indexOf doesn't work in IE8 and lower. - contains.js
🌐
Futurestud.io
futurestud.io › tutorials › check-if-a-string-includes-all-strings-in-javascript-or-node-js
Check If a String Includes All Strings in JavaScript/Node.js/TypeScript
December 17, 2020 - JavaScript comes with helpful array and string methods that will help you determine whether a base string contains all values from a list of strings. You can use the Array#every in combination with the String#includes method to check if all items from the candidate list are part of the base string:
🌐
freeCodeCamp
forum.freecodecamp.org › javascript
Javascript: Correct Syntax to find if string exists in Array - JavaScript - The freeCodeCamp Forum
May 13, 2022 - In the DO…WHILE loop I need to extract 5000 items from a list (LookupList) and create a new list (arrayAll). I need help validating which of these lines is correct, or if not what is the correct syntax: arrayAll.push.apply(arrayAll, arrayBatch); arrayAll = arrayAll.concat(arrayBatch); Then I want to find if the string (LookupField) exists in the new list (arrayAll).
🌐
W3Schools
w3schools.com › jsref › jsref_includes.asp
JavaScript String includes() Method
❮ Previous JavaScript String ... text.includes("world"); Try it Yourself » · More examples below. The includes() method returns true if a string contains a specified string....
🌐
CoreUI
coreui.io › answers › how-to-check-if-an-array-contains-a-value-in-javascript
How to check if an array contains a value in JavaScript · CoreUI
May 12, 2026 - 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.