The String indexOf() method

By

Learn how the JavaScript indexOf() method returns the position of the first occurrence of a substring, or -1 when it is not found, plus an optional start index.

~~~

indexOf() gives the position of the first occurrence of the string passed as parameter in the current string. It returns -1 if the string is not found:

'JavaScript'.indexOf('Script') //4
'JavaScript'.indexOf('JavaScript') //0
'JavaScript'.indexOf('aSc') //3
'JavaScript'.indexOf('C++') //-1

Positions start at 0, so a match at the very beginning returns 0, not 1.

The search is case sensitive. 'Script' and 'script' are different strings:

'JavaScript'.indexOf('script') //-1

Setting a starting point

You can pass a second parameter to set the position where the search starts:

'a nice string'.indexOf('nice') !== -1 //true
'a nice string'.indexOf('nice', 3) !== -1 //false
'a nice string'.indexOf('nice', 2) !== -1 //true

'nice' starts at position 2. Starting the search at 3 skips past it, so the match is lost.

This is useful when you want to find the second occurrence of something. Search once, then search again starting right after the first match.

Finding where something is, not just if it’s there

The position is the real value of indexOf(). Once you have it, you can cut the string with slice(). Here we extract everything after the colon:

const line = 'name: Flavio'
const pos = line.indexOf(':')

line.slice(pos + 2) //'Flavio'

If you only need to know whether the substring exists, includes() reads better:

'JavaScript'.includes('Script') //true

There’s also lastIndexOf(), which searches from the end and gives you the last occurrence instead of the first.

What if you pass something that’s not a string?

The parameter gets converted to a string before the search. Passing a number works, because it becomes its string form:

'route 66'.indexOf(66) //6

And searching for an empty string always matches, right at the position where the search starts:

'JavaScript'.indexOf('') //0

Be careful with the -1 check

Here is the classic mistake with this method. indexOf() returns 0 when the match is at the start, and 0 is falsy:

const url = 'https://flaviocopes.com'

if (url.indexOf('https')) {
  //never runs! indexOf returned 0
}

The match is there, but the if sees 0 and skips the block. Always compare against -1 explicitly:

if (url.indexOf('https') !== -1) {
  //runs
}

Or avoid the problem and use includes(), which returns a real boolean.

~~~

Related posts about js: