String.prototype.includes()
Tests whether a string contains a given substring, returning true or false.
includes(searchString)
includes(searchString, position)- Added in JavaScript ECMAScript 2015
Parameters
| Parameter | Type | Description |
|---|---|---|
$searchString | string | The substring to search for. Cannot be a regex; all other values are coerced to strings, so omitting it searches for the literal text "undefined". |
$positionoptional | number= 0 | The index at which to begin searching. |
Return value
booleantrue if searchString is found anywhere in the string (including when it is empty); otherwise false.
Errors
Throws a TypeError if searchString is a regular expression.
includes() answers the only question most substring searches actually ask: is it in there? It replaced the older str.indexOf(x) !== -1 idiom, where the -1 comparison was easy to get wrong (> 0 silently misses a match at index 0).
Things that catch people out
- It is case-sensitive. Normalise both sides —
a.toLowerCase().includes(b.toLowerCase())— for a user-facing search, and considernormalize("NFC")when accents may be typed either composed or decomposed. - A regex argument throws. Passing
/foo/raisesTypeErrorby design, so the method can never be confused for a pattern match. UseRegExp.prototype.test()for patterns. - An empty needle is always found, returning
truefor any haystack including"". Filter empty search terms before you use the result to decide whether to show "no matches". - It searches code units. A composed é does not match a decomposed e + ◌́ even though both render identically.
Position
The second argument sets where the search begins. It only moves the start point; the match may extend past it, and a negative value behaves like 0.
Example
When to use it
- Filter a list of items by a typed search term
- Check a URL or path for a marker segment before routing
- Test a log line for an error keyword
- Confirm a comma-separated header advertises a value
Frequently asked questions
How do I check if a string contains a substring in JavaScript?
Use str.includes(substring), which returns true or false. It is case-sensitive, so lowercase both sides when the comparison should ignore case.
Why does includes() throw a TypeError with a regex?
The specification rejects regular expressions so that includes() is never mistaken for pattern matching. Use /pattern/.test(str) instead.
What is the difference between includes() and indexOf()?
includes() returns a boolean; indexOf() returns the position or -1. Use indexOf() only when you need where the match is, not just whether it exists.
More examples
A case-insensitive, accent-tolerant filter
Decomposing and stripping diacritics makes "zur" match "Zürich". The last line is the trap: an empty query returns the full list, so guard it before showing results.
const fold = (s) =>
s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase();
const cities = ["São Paulo", "Zürich", "Dublin"];
const find = (q) => cities.filter((c) => fold(c).includes(fold(q)));
console.log(find("zur")); // [ 'Zürich' ]
console.log(find("sao")); // [ 'São Paulo' ]
console.log(find("")); // all three — empty query matches everythingincludes() vs indexOf() for a hit at index 0
A match at index 0 is falsy as a number and fails a > 0 test. includes() removes the comparison entirely, which is why it is the safer default.
const path = "admin/users";
console.log(path.includes("admin")); // true
console.log(path.indexOf("admin")); // 0
console.log(path.indexOf("admin") > 0); // false — the classic bug
console.log(path.indexOf("admin") !== -1); // true — correct comparison
console.log(path.includes("users", 6)); // true
console.log(path.includes("admin", 1)); // false
Discussion