Start learning free

LESSON 65 OF 344 · STRINGS I

String Find in JavaScript: indexOf and lastIndexOf

Lesson Read the full explanation

In JavaScript, you can find the index of a substring using indexOf():

s.indexOf(sub)         // returns index of first occurrence, or -1 if not found
s.lastIndexOf(sub)     // returns index of last occurrence
s.indexOf(sub, start)  // search starting from index `start`

Here are some examples:

let sentence = "Hello World";
let idx = sentence.indexOf("World");
console.log(idx);  // 6

console.log(sentence.indexOf("xyz"));  // -1  (not found)

The index returned is the position of the first character of the found substring.


Assignment
Follow the Coding Tutorial and find the index of "World" in sentence!


Hint
Use sentence.indexOf("World") and assign the result to idx.

STEP 1 OF 1
    Ctrl + Enter to check

    JAVASCRIPT · STRINGS I

    String Find in JavaScript, explained

    What string find does

    Finding a substring means asking where a piece of text starts inside a longer string. In JavaScript the main tool is the indexOf() method. You call it on a string and pass the text to look for. It returns a number: the index of the first match, or -1 when the text is not there.

    let sentence = "Hello World";
    let idx = sentence.indexOf("World");
    console.log(idx);                      // 6
    console.log(sentence.indexOf("xyz"));  // -1
    

    Indexes start at 0, so "H" is at 0, "e" at 1, and the space at 5. The "W" of "World" is at 6. The returned index is always the position of the first character of the match, not the last.

    The three forms

    s.indexOf(sub)         // index of the first occurrence, or -1
    s.lastIndexOf(sub)     // index of the last occurrence, or -1
    s.indexOf(sub, start)  // search starting from index start
    

    When the text appears more than once, the form you pick decides which match you get:

    let s = "Hello World";
    console.log(s.indexOf("o"));      // 4
    console.log(s.lastIndexOf("o"));  // 7
    console.log(s.indexOf("o", 5));   // 7
    

    The first "o" is at index 4, inside "Hello". lastIndexOf scans from the end and finds the one in "World" at index 7. Passing 5 as the second argument to indexOf makes it skip everything before index 5, so it also lands on 7.

    Gotchas

    Matching is case sensitive

    "Hello World".indexOf("hello") is -1, because "h" and "H" are different characters. To ignore case, convert both strings with toLowerCase() first.

    -1 is truthy, 0 is falsy

    The "not found" value is -1, and in a condition -1 counts as true. Index 0, a match at the very start, counts as false. So this check is wrong:

    if (s.indexOf("xyz")) {
        console.log("found");   // runs, even though nothing was found
    }
    

    Always compare with -1 directly:

    if (s.indexOf("xyz") !== -1) {
        console.log("found");
    }
    

    When you only need a yes or no answer, s.includes("xyz") is clearer and avoids the trap.

    Only the first match, unless you loop

    To collect every position, search again from just after the previous match:

    let t = "banana";
    let i = t.indexOf("a");
    while (i !== -1) {
        console.log(i);            // 1, then 3, then 5
        i = t.indexOf("a", i + 1);
    }
    

    The empty string and out-of-range starts

    s.indexOf("") is 0, since the empty string matches at the start. A start index below 0 is treated as 0, and a start beyond the end of the string just gives -1 for any non-empty text.

    The exercise, step by step

    The starter code gives one variable:

    let sentence = "Hello World";
    

    The task is to find where "World" starts. That takes a single new line.

    1. Declare idx below sentence, with let.
    2. Call indexOf on sentence and pass "World". The method returns 6, and that number is stored in idx.

    The solution in JavaScript

    let sentence = "Hello World";
    
    let idx = sentence.indexOf("World");
    

    You can check the result with console.log(idx), which prints 6. The method never changes sentence. Strings in JavaScript are immutable, so every string method gives you a result and leaves the original alone.

    Using the index

    An index is most useful together with other string tools. slice cuts a string from a position, so you can take everything from the match onward:

    console.log(sentence.slice(idx));  // World
    

    Common mistakes

    The first mistake is forgetting that an index counts characters from zero. In "Hello World" the word "World" starts at 6 even though it is the second word, and the string has 11 characters, so the last index is 10. The match ends at idx + "World".length, which is 11, the position just after the final letter.

    The second mistake is feeding -1 into other code without checking. For example, url.slice(url.indexOf("/")) looks harmless, but if there is no slash the index is -1, and slice(-1) means "the last character". The program doesn't crash. It quietly returns the wrong answer. Check for -1 before using the index.

    The third mistake is confusing overlapping matches. In "aaa", indexOf("aa") is 0 and lastIndexOf("aa") is 1. The two matches overlap, and each method simply reports the one nearest its own end of the string.

    Using the index to take a string apart

    Once you know where a separator is, you can cut the string around it with slice. For an address like "ann@example.org", find the "@" and take the text on each side:

    const email = "ann@example.org";
    const at = email.indexOf("@");
    console.log(email.slice(0, at));      // ann
    console.log(email.slice(at + 1));     // example.org
    

    The first slice stops just before the match, and the second starts one position after it, to skip the "@" itself. This pattern comes up constantly when you process text, and it all starts with indexOf.

    Key takeaways

    • indexOf(sub) returns the index of the first character of the first match, or -1.
    • lastIndexOf(sub) finds the last match, and indexOf(sub, start) begins at a position you choose.
    • The search is case sensitive.
    • Compare the result with -1. Never use it directly as a condition, because -1 is truthy and 0 is falsy.
    • Use includes when you only need to know whether the text is present.
    Keep going with JavaScriptAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free