String.prototype.lastIndexOf()
Returns the index of the last occurrence of a substring, searching backwards from the end.
lastIndexOf(searchString)
lastIndexOf(searchString, position)- Added in JavaScript ECMAScript 1
Parameters
| Parameter | Type | Description |
|---|---|---|
$searchString | string | The substring to search for. All values are coerced to strings, so omitting it searches for the literal text "undefined". |
$positionoptional | number= Infinity | The match must start at or before this index. Values above str.length search the whole string; values below 0 behave like 0, so only index 0 is examined. |
Return value
numberThe index of the last occurrence of searchString that starts at or before position, or -1 if it is not found.
lastIndexOf() scans backwards and reports where the final match starts. The returned index is still measured from the left, which is what makes it composable with slice().
position is a start bound, not an end bound
The optional second argument constrains where the match may begin, not where it may finish. "canal".lastIndexOf("a", 2) is 1: the match at index 3 begins after the bound, so it is excluded. A negative position collapses to 0, meaning only a match starting at index 0 can be found — "canal".lastIndexOf("c", -5) is 0 but "canal".lastIndexOf("a", 0) is -1. Because the default is Infinity rather than 0, a NaN position searches the entire string instead of clamping to the front — the opposite of indexOf().
The classic use
Splitting on the last separator: a file extension, the final path segment, a package's version suffix. Guard the not-found case first — lastIndexOf(".") returning -1 makes slice(-1 + 1) become slice(0), which silently hands back the whole string as if it were the extension.
An empty search string returns min(position, str.length), so it never reports -1.
Example
When to use it
- Extract a file extension from a filename
- Take the last path segment after the final slash
- Trim everything after the last comma in a formatted list
- Find the closing occurrence of a delimiter when scanning backwards
Frequently asked questions
How do I get the file extension from a filename in JavaScript?
Use name.slice(name.lastIndexOf(".") + 1), but check first that lastIndexOf(".") is greater than 0, otherwise a name with no dot returns itself.
What does the second argument of lastIndexOf() do?
It caps where the match may start, not where it may end, and defaults to Infinity. "canal".lastIndexOf("a", 2) is 1 because the match at index 3 starts past the bound.
What is the difference between indexOf() and lastIndexOf()?
indexOf() scans forwards and returns the first match; lastIndexOf() scans backwards and returns the last. Both report a left-based index and both return -1 when nothing matches.
More examples
A safe file-extension helper
The dot > 0 guard rejects both "no dot at all" (-1) and leading-dot filenames (0). The final line shows what happens without it: -1 + 1 is 0, so slice returns the whole name.
function extension(name) {
const dot = name.lastIndexOf(".");
return dot > 0 ? name.slice(dot + 1) : "";
}
console.log(extension("report.final.pdf")); // "pdf"
console.log(JSON.stringify(extension("README"))); // ""
console.log(JSON.stringify(extension(".gitignore"))); // "" — dotfile, not an ext
// Without the guard:
console.log("README".slice("README".lastIndexOf(".") + 1)); // "README"Last path segment and directory
One index splits the path into both halves. When there is no slash, the basename still comes out right by accident, but the directory half becomes an empty string — handle that case explicitly.
const p = "/var/log/nginx/access.log";
const cut = p.lastIndexOf("/");
console.log(p.slice(cut + 1)); // "access.log"
console.log(p.slice(0, cut)); // "/var/log/nginx"
const flat = "access.log";
console.log(flat.slice(flat.lastIndexOf("/") + 1)); // "access.log"
console.log(JSON.stringify(flat.slice(0, flat.lastIndexOf("/")))); // ""
Discussion