String Methods
Strings carry a generous standard library — search, slice, split, transform. Every method returns a new string (or array of strings), never mutates the original. This page is the practical reference you'll come back to: what each method does, what it returns and the small gotchas that catch people out.
Searching: indexOf, includes, startsWith, endsWith
const s = "the quick brown fox";
s.indexOf("quick"); // 4
s.indexOf("QUICK"); // -1 — case-sensitive
s.indexOf("o", 12); // 17 — start from index 12
s.lastIndexOf("o"); // 17
s.includes("brown"); // true — simpler boolean check (ES6+)
s.startsWith("the"); // true
s.endsWith("fox"); // true
s.startsWith("quick", 4); // true — second arg is start indexSlicing: slice, substring, substr
const s = "Hello, world"; s.slice(0, 5); // "Hello" — start, end (exclusive) s.slice(7); // "world" — to the end s.slice(-5); // "world" — negative indexes count from the end s.slice(-5, -1); // "worl" s.substring(0, 5); // "Hello" s.substring(5, 0); // "Hello" — substring swaps args if start > end s.substring(-5, 5); // "Hello" — treats negatives as 0! s.substr(7, 5); // "world" — start + length; deprecated
Splitting and joining
"a,b,c".split(","); // ["a", "b", "c"]
"a,b,c".split(",", 2); // ["a", "b"] — second arg = max parts
"hello".split(""); // ["h", "e", "l", "l", "o"]
"hello".split(/(?=.)/); // works for surrogate pairs? not really — use [...s]
" one two ".split(/\s+/); // ["", "one", "two", ""]
["a", "b", "c"].join("-"); // "a-b-c"
[1, 2, 3].join(); // "1,2,3" — default separator is ","
[1, 2, 3].join(""); // "123"A handy idiom: s.split(separator).map(f).join(separator) lets you transform every part of a delimited string without writing a manual loop.
Case and whitespace
"Hello".toUpperCase(); // "HELLO"
"HELLO".toLowerCase(); // "hello"
// Locale-aware versions matter for Turkish, German, etc.
"İstanbul".toLowerCase(); // "i̇stanbul" — incorrect for tr-TR
"İstanbul".toLocaleLowerCase("tr-TR"); // "istanbul"
" hello ".trim(); // "hello"
" hello ".trimStart(); // "hello "
" hello ".trimEnd(); // " hello"
// padStart / padEnd — handy for fixed-width formatting
"5".padStart(3, "0"); // "005"
"abc".padEnd(6, "."); // "abc..."
"hi".repeat(3); // "hihihi"
"hi".repeat(0); // ""
"hi".repeat(-1); // RangeErrorReplace and replaceAll
const s = "the cat sat on the mat";
s.replace("the", "a"); // "a cat sat on the mat" — only first!
s.replace(/the/g, "a"); // "a cat sat on a mat" — global regex
s.replaceAll("the", "a"); // "a cat sat on a mat" — ES2021
// Function as the replacement gets the match plus capture groups
"price: 5".replace(/\d+/, m => Number(m) * 2); // "price: 10"
// $1, $2 reference capture groups
"John Smith".replace(/(\w+) (\w+)/, "$2 $1"); // "Smith John"
// Useful escape characters in the replacement string:
// $$ -> literal $
// $& -> the whole match
// $` -> text before the match
// $' -> text after the matchmatch, matchAll, search
const s = "tel: 415-555-2671 fax: 415-555-9999";
s.match(/\d+/); // ["415", index: 5, ...] — first match
s.match(/\d+/g); // ["415", "555", "2671", "415", "555", "9999"]
const re = /(\d{3})-(\d{3})-(\d{4})/g;
for (const m of s.matchAll(re)) {
console.log(m[0], "area:", m[1]);
}
s.search(/\d+/); // 5 — index of first regex match (or -1)415-555-2671 area: 415 415-555-9999 area: 415
Unicode-aware comparisons and normalisation
Two strings can look identical but contain different code-point sequences — for example, "é" written as a precomposed character vs "e" + combining acute accent. They will not be === equal until you normalise them.
const a = "café"; // length 4
const b = "cafe\u0301"; // length 5, looks the same
a === b; // false
a.normalize() === b.normalize(); // true
a.localeCompare(b, "fr", { sensitivity: "base" }); // 0 — considered equalUse .normalize() (default form "NFC") before storing or comparing user input that contains accented characters.
Tiny cheat-sheet
Check substring —
s.includes(x),s.startsWith(x),s.endsWith(x).Slice a range —
s.slice(a, b)(supports negatives).Split / join —
s.split(sep),arr.join(sep). Use a regex separator for whitespace.Pad and trim —
padStart,padEnd,trim,trimStart,trimEnd.Search and replace —
replaceAllorreplacewith a global regex.Iterate characters safely —
for (const ch of s)or[...s].Compare user text —
localeComparewith a locale;normalize()before equality.
Together with template literals, these methods cover almost every text-manipulation problem you'll meet outside of heavy parsing. For anything more complex than what's here, regular expressions are usually the next stop.