JavaScript provides built-in search methods to check if text contains a word, locate its index, or match regular expression patterns. Choosing the right search method keeps your conditions readable and avoids fragile index checks.
Each string search method answers a slightly different question:
includes(sub): Returns true or false when checking whether a substring exists anywhere inside the text.startsWith(sub) / endsWith(sub): Checks prefixes and suffixes, which is ideal for URLs, file extensions, or command parsing.indexOf(sub) / lastIndexOf(sub): Returns the zero-based position of the first or last match, or -1 when nothing matches.matchAll(regex): Finds every regular expression match along with capture groups and positions.In real apps, normalize letter case with toLowerCase() before calling includes() so search filters behave predictably for users.
const filePath = "/uploads/invoices/2026-May-Report.pdf";
const query = "may";
const isPdf = filePath.toLowerCase().endsWith(".pdf");
const matchesQuery = filePath.toLowerCase().includes(query);
const firstSlash = filePath.indexOf("/", 1); // Start search after index 0
const prices = "Items: $12, $45, and $99";
const foundNumbers = [...prices.matchAll(/\$(\d+)/g)].map((m) => Number(m[1]));
console.log({ isPdf, matchesQuery, firstSlash, foundNumbers });
includes() Beats indexOf() !== -1Older JavaScript code checked str.indexOf("word") !== -1 or str.indexOf("word") >= 0. Modern ES6 str.includes("word") states your intent directly as a boolean and removes off-by-one confusion with 0 being falsy.
"JavaScript".includes("script") returns false. Always lowercase both strings for user search inputs.indexOf() result 0 as falsy: Checking if (str.indexOf("js")) fails when "js" starts at index 0, because 0 is falsy.matchAll() without the /g flag: Passing a regex without the global g flag to matchAll() throws a TypeError at runtime.search() and indexOf()?indexOf() searches only for a plain string and accepts a starting index. search() accepts a regular expression, ignores a global flag, and always starts from index 0.
Use [...text.matchAll(/word/gi)].length, or split carefully on word boundaries when matching whole words.
includes() accept a starting position?Yes, pass a second number argument like text.includes("api", 8) to begin searching from index 8 onward.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
Experiment with the code from this lesson in our interactive playground.