ECMAScript 6 introduced String.prototype.includes:

const string = "foo";
const substring = "oo";

console.log(string.includes(substring)); // true
Run code snippetEdit code snippet Hide Results Copy to answer Expand

String.prototype.includes is case-sensitive and is not supported by Internet Explorer without a polyfill.

In ECMAScript 5 or older environments, use String.prototype.indexOf, which returns -1 when a substring cannot be found:

var string = "foo";
var substring = "oo";

console.log(string.indexOf(substring) !== -1); // true
Run code snippetEdit code snippet Hide Results Copy to answer Expand

🌐
W3Schools
w3schools.com › js › js_string_methods.asp
JavaScript String Methods
JS Examples JS HTML DOM JS HTML Input JS HTML Objects JS HTML Events JS Browser JS Editor JS Exercises JS Quiz JS Website JS Syllabus JS Study Plan JS Interview Prep JS Bootcamp JS Certificate ... Javascript strings are primitive and immutable: All ...
🌐
GeeksforGeeks
geeksforgeeks.org › javascript › javascript-strings
JavaScript Strings - GeeksforGeeks
A JavaScript String is a sequence of characters, typically used to represent text. In JavaScript, there is no character type (Similar to Python and different from C, C++ and Java), so a single character string is used when we need a character.
Published   June 11, 2026
🌐
W3Schools
w3schools.com › js › js_strings.asp
JavaScript Strings
JS Examples JS HTML DOM JS HTML ... Interview Prep JS Bootcamp JS Certificate ... A JavaScript string is zero or more characters written inside quotes....
🌐
W3Schools
w3schools.com › jsref › jsref_includes.asp
JavaScript String includes() Method
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP W3.CSS C C++ C# HOW TO BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS DSA TYPESCRIPT ANGULAR ANGULARJS GIT POSTGRESQL MONGODB ASP AI R GO KOTLIN SWIFT SASS VUE GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE INTRO TO PROGRAMMING INTRO TO HTML & CSS BASH RUST TOOLS ... JS String JS Number JS Boolean JS BigInt JS Symbol JS undefined JS null JS undefined vs null JS Constructors
🌐
Medium
medium.com › @akxay › javascript-string-methods-5588830241ed
JavaScript String Methods
October 10, 2024 - Syntax: str.split(separator, limit) => separator (optional): Specifies where to divide the string.If an empty string is used, the string will be split into individual characters. => limit (optional): Specifies the maximum number of splits. // Example 1: Splitting a Sentence into Words const sentence = "JavaScript is fun"; const words = sentence.split(" "); console.log(words); // Output: ['JavaScript', 'is', 'fun'] // Example 2: Splitting by a Character const date = "2024-10-10"; const parts = date.split("-"); console.log(parts); // Output: ['2024', '10', '10'] // Example 3: Splitting into Characters const word = "Hello"; const characters = word.split(""); console.log(characters); // Output: ['H', 'e', 'l', 'l', 'o']
Find elsewhere
🌐
freeCodeCamp
freecodecamp.org › news › what-is-a-string-in-javascript
What is a String in JS? The JavaScript String Variable Explained
November 7, 2024 - A string represents textual data, which is a fundamental part of many applications. You can also use strings to interact with users through prompts, alerts, and other forms of user input and output.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Learn_web_development › Core › Scripting › Strings
Handling text — strings in JavaScript - Learn web development | MDN
Next, we'll turn our attention to strings — this is what pieces of text are called in programming. In this article, we'll look at all the common things that you really ought to know about strings when learning JavaScript, such as creating strings, escaping quotes in strings, and joining strings ...
🌐
Medium
medium.com › @rajeswaridepala › strings-in-javascript-2e542c319493
Strings in Javascript. As I said to you before, a string is a… | by Rajeswari Depala | Medium
January 28, 2025 - Strings in Javascript As I said to you before, a string is a sequence of characters enclosed in single quotes (‘’) , double quotes (“ ”) and back ticks(``). Strings in JavaScript can be …
🌐
freeCodeCamp
freecodecamp.org › news › how-to-check-if-a-string-contains-a-substring-javascript
How to Check if a String Contains a Substring in JavaScript
October 7, 2022 - When you're working with a JavaScript program, you might need to check whether a string contains a substring. A substring is a string inside another string. Specifically, you might need to check whether a word contains a specific character or a speci...
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
}
🌐
freeCodeCamp
freecodecamp.org › news › javascript-string-contains-how-to-use-js-includes
JavaScript String Contains – How to use JS .includes()
November 5, 2021 - The position parameter is an optional number for the starting search position in the str. If the position parameter is omitted then the default is zero. If the search-string is found then it will return true.
🌐
NestJS
docs.nestjs.com › pipes
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).
🌐
TypeScript
typescriptlang.org › docs › handbook › 2 › everyday-types.html
TypeScript: Documentation - Everyday Types
JavaScript does not have a special runtime value for integers, so there’s no equivalent to int or float - everything is simply number ... The type names String, Number, and Boolean (starting with capital letters) are legal, but refer to some special built-in types that will very rarely appear in your code.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Global_Objects › String › indexOf
String.prototype.indexOf() - JavaScript | MDN
The indexOf() method of String values searches this string and returns the index of the first occurrence of the specified substring. It takes an optional starting position and returns the first occurrence of the specified substring at an index greater than or equal to the specified number.