String.prototype.includes()

Tests whether a string contains a given substring, returning true or false.

Signature
includes(searchString)
includes(searchString, position)
  • Added in JavaScript ECMAScript 2015

Parameters

ParameterTypeDescription
$searchStringstringThe substring to search for. Cannot be a regex; all other values are coerced to strings, so omitting it searches for the literal text "undefined".
$positionoptionalnumber= 0The 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 consider normalize("NFC") when accents may be typed either composed or decomposed.
  • A regex argument throws. Passing /foo/ raises TypeError by design, so the method can never be confused for a pattern match. Use RegExp.prototype.test() for patterns.
  • An empty needle is always found, returning true for 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · javascript
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 everything

includes() 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.

Example · javascript
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

  • Be the first to comment on this lesson.