How to Check if a String Contains a Substring in JavaScript
A fundamental operation in text processing is to check if a string contains a smaller piece of text, known as a substring. This is essential for searching, filtering, and validating data. Modern JavaScript provides a simple, direct, and highly readable method for this task: String.prototype.includes().
This guide will teach you how to use the .includes() method for both case-sensitive and case-insensitive searches. You will also learn about the older .indexOf() method and understand why .includes() is the recommended best practice for modern code.
The Core Method (Recommended): String.prototype.includes()
The .includes() method is the modern and standard way to check for a substring. Its purpose is to provide a clear, direct, and readable answer to the question, "Does this string contain this other string?"
Syntax
myString.includes(substringToFind)
where:
substringToFind: The string to search for.- Returns: A boolean:
trueif the substring is found, otherwisefalse.
Solution
const mainString = "The quick brown fox jumps over the lazy dog.";
const searchTerm = "fox";
const hasSubstring = mainString.includes(searchTerm);
console.log(hasSubstring); // Output: true
if (mainString.includes("lazy")) {
console.log("The word 'lazy' was found.");
}
// Output: The word 'lazy' was found.
Output:
true
The word 'lazy' was found.
This method is case-sensitive by default.
How to Perform a Case-Insensitive Search
The .includes() method is case-sensitive ('Hello'.includes('hello') is false). To perform a case-insensitive search, the standard practice is to convert both the main string and the search term to the same case (typically lowercase) before the comparison.
const mainString = "The Quick Brown Fox";
const searchTerm = "quick";
// Convert both strings to lowercase for the comparison
const hasSubstringCaseInsensitive = mainString.toLowerCase().includes(searchTerm.toLowerCase());
console.log(hasSubstringCaseInsensitive); // Output: true
This is the most reliable and readable way to perform a case-insensitive check.
How to Check if a String Does NOT Contain a Substring
To check if a string doesn't contain a substring, you simply negate the result of the .includes() method using the logical NOT operator (!).
const mainString = "Hello, world!";
const searchTerm = "goodbye";
if (!mainString.includes(searchTerm)) {
console.log(`The string does NOT contain '${searchTerm}'.`);
} else {
console.log(`The string CONTAINS '${searchTerm}'.`);
}
Output:
The string does NOT contain 'goodbye'.
The Older Method: String.prototype.indexOf()
Before .includes() was introduced in ES6, the standard way to check for a substring was with the .indexOf() method. This method returns the index (the starting position) of the substring.
The logic:
- If the substring is found,
.indexOf()returns its starting index (a number0or greater). - If the substring is not found, it returns
-1.
Therefore, you can check for a substring by checking if the result is not equal to -1.
Solution:
const mainString = "Hello, world!";
const searchTerm = "world";
const index = mainString.indexOf(searchTerm);
console.log(index); // Output: 7
if (mainString.indexOf(searchTerm) !== -1) {
console.log("The substring was found.");
} else {
console.log("The substring was not found.");
}
Why .includes() is Better:
The if (str.includes(sub)) syntax is more explicit and readable than if (str.indexOf(sub) !== -1). The .includes() method was created specifically to simplify this common check, making your code's intent clearer.
Conclusion
Checking for a substring is a simple but essential task in JavaScript.
The key takeaways are:
- The
.includes()method is the modern, recommended best practice. It is clear, readable, and returns a direct booleantrueorfalse. - To perform a case-insensitive search, convert both the main string and the substring to the same case before calling
.includes():str.toLowerCase().includes(sub.toLowerCase()). - To check if a string does not contain a substring, use the logical NOT operator:
!str.includes(sub). - The older
.indexOf() !== -1method works perfectly well but is less readable than.includes().