JavaScript String Methods Mastery: Complete Guide from slice() to replaceAll()
Master every essential JavaScript string method. From search with includes() and indexOf() to transformation with template literals and replaceAll(). Includes regex patterns, common recipes, and interview questions.
- 1. JavaScript Type Coercion Mastery: A Senior Engineer's Guide to the Chaos
- 2. JavaScript Runtime Deep Dive: Event Loop, Call Stack & Async Execution
- 3. Mastering JavaScript Callbacks: From Sync to Async & The Event Loop
- 4. JavaScript Closures Deep Dive: Mastering Lexical Scope & Memory
- 5. JavaScript Object Prototyping Mastery: A Visual Guide to Inheritance
- 6. Demystifying the JavaScript 'this' Keyword: A Visual Guide
- 7. JavaScript Promises & Promise Chaining Mastery: From Callbacks to Async Flow
- 8. JavaScript Array Methods Mastery: Complete Guide from map() to reduce()
- 9. JavaScript Map & Set Mastery: Complete Guide to Modern Data Structures
- 10. JavaScript String Methods Mastery: Complete Guide from slice() to replaceAll()
- 11. JavaScript Regular Expressions Mastery: Real-World Patterns & Validation
Introduction
Strings are everywhere in JavaScript—user input, API responses, file paths, URLs, template rendering. Yet many developers rely on just a handful of methods like split() and replace(), missing out on the full power of JavaScript's string API.
This comprehensive guide covers every essential string method, organized by purpose. You'll learn search techniques, extraction patterns, transformation tricks, and modern ES2021+ additions. Whether you're preparing for interviews or leveling up your daily code, this is your definitive reference.
ℹ️ note[!NOTE] Strings in JavaScript are immutable. Every string method returns a new string—the original is never modified.
The String Methods Landscape
JavaScript string methods fall into several categories:
| Category | Methods | Purpose |
|---|---|---|
| Search | indexOf(), lastIndexOf(), includes(), startsWith(), endsWith(), search() | Find characters or substrings |
| Pattern Matching | match(), matchAll(), replace(), replaceAll() | Work with regex patterns |
| Extraction | slice(), substring(), charAt(), at() | Extract parts of strings |
| Transformation | toUpperCase(), toLowerCase(), trim(), trimStart(), trimEnd(), repeat(), padStart(), padEnd() | Change string format |
| Splitting & Joining | split(), concat() | Break apart or combine strings |
| Template Literals | `${}`, tagged templates | Modern string creation |
1. Search Methods
1.1 indexOf() - Find First Occurrence
Returns the index of the first occurrence of a substring, or -1 if not found.
const message = 'Hello, World! Hello, JavaScript!';
console.log(message.indexOf('Hello')); // 0
console.log(message.indexOf('JavaScript')); // 21
console.log(message.indexOf('Python')); // -1
// Search from a specific position (second argument)
console.log(message.indexOf('Hello', 5)); // 14
1.2 lastIndexOf() - Find Last Occurrence
Returns the index of the last occurrence of a substring, or -1.
const path = '/users/admin/users/profile';
console.log(path.lastIndexOf('users')); // 13
console.log(path.indexOf('users')); // 1
function getExtension(filename) {
const lastDot = filename.lastIndexOf('.');
return lastDot === -1 ? '' : filename.slice(lastDot + 1);
}
console.log(getExtension('photo.jpg')); // 'jpg'
console.log(getExtension('archive.tar.gz')); // 'gz'
console.log(getExtension('README')); // ''
1.3 includes() - Check if Substring Exists
Returns true if the string contains the substring, false otherwise.
const sentence = 'JavaScript is awesome!';
console.log(sentence.includes('awesome')); // true
console.log(sentence.includes('terrible')); // false
// Case-sensitive!
console.log(sentence.includes('javascript')); // false
console.log(sentence.includes('JavaScript')); // true
Better than indexOf():
// ❌ Old way
if (sentence.indexOf('awesome') !== -1) { /* ... */ }
// ✅ Modern way
if (sentence.includes('awesome')) { /* ... */ }
1.4 startsWith() & endsWith() - Check Boundaries
const url = 'https://api.example.com/users';
console.log(url.startsWith('https')); // true
console.log(url.startsWith('http')); // true
console.log(url.endsWith('/users')); // true
console.log(url.endsWith('.com')); // false
// Start checking from a specific position
console.log(url.startsWith('api', 8)); // true
function isImageFile(filename) {
const lower = filename.toLowerCase();
return ['.jpg', '.jpeg', '.png', '.gif', '.webp']
.some(ext => lower.endsWith(ext));
}
console.log(isImageFile('photo.JPG')); // true
console.log(isImageFile('doc.pdf')); // false
1.5 search() - Find with Regex
Returns the index of the first match of a regex, or -1.
const text = 'Contact us at support@example.com';
console.log(text.search(/\d+/)); // -1 (no digits)
console.log(text.search(/@/)); // 21
console.log(text.search(/[A-Z]/)); // 0 ('C' in 'Contact')
Difference from indexOf():
search()accepts a regexindexOf()accepts only a string
2. Pattern Matching Methods
2.1 match() - Find Matches
Returns an array of matches, or null.
const text = 'My phone: 123-456-7890, Office: 098-765-4321';
// Without 'g' flag — returns first match with details
const firstMatch = text.match(/\d{3}-\d{3}-\d{4}/);
console.log(firstMatch[0]); // '123-456-7890'
console.log(firstMatch.index); // 10
// With 'g' flag — returns all matches
const allMatches = text.match(/\d{3}-\d{3}-\d{4}/g);
console.log(allMatches);
// ['123-456-7890', '098-765-4321']
2.2 matchAll() - Detailed Match Iterator
Returns an iterator of all matches with full details (groups, indices).
const text = 'Price: $25.99, Tax: $3.50';
const regex = /\$(\d+\.\d{2})/g;
for (const match of text.matchAll(regex)) {
console.log(`Full: ${match[0]}, Amount: ${match[1]}, Index: ${match.index}`);
}
// Full: $25.99, Amount: 25.99, Index: 7
// Full: $3.50, Amount: 3.50, Index: 20
💡 tip[!TIP]
matchAll()is superior tomatch()with thegflag because it preserves capture groups and match positions.
2.3 replace() - Replace First Match
Replaces the first occurrence of a pattern.
const text = 'Hello World! Hello JavaScript!';
// Replace string
console.log(text.replace('Hello', 'Hi'));
// 'Hi World! Hello JavaScript!'
// Replace with regex
console.log(text.replace(/Hello/g, 'Hi'));
// 'Hi World! Hi JavaScript!'
function slugify(title) {
return title
.toLowerCase()
.replace(/[^a-z0-9\s-]/g, '') // Remove special chars
.replace(/\s+/g, '-') // Spaces to hyphens
.replace(/-+/g, '-') // Collapse multiple hyphens
.replace(/^-|-$/g, ''); // Trim hyphens
}
console.log(slugify('Hello, World! 🌍'));
// 'hello-world'
Using Capture Groups:
const date = '2026-02-12';
// Reformat from YYYY-MM-DD to DD/MM/YYYY
const formatted = date.replace(
/(\d{4})-(\d{2})-(\d{2})/,
'$3/$2/$1'
);
console.log(formatted); // '12/02/2026'
2.4 replaceAll() - Replace All Occurrences (ES2021)
Replaces all occurrences without needing the g flag.
const text = 'foo-bar-baz';
// ❌ Old way (requires regex with /g flag)
console.log(text.replace(/\-/g, '_')); // 'foo_bar_baz'
// ✅ Modern way (ES2021)
console.log(text.replaceAll('-', '_')); // 'foo_bar_baz'
💜 important[!IMPORTANT]
replaceAll()with a regex argument requires thegflag, or it throws aTypeError. For simple string replacements, just pass a string.
3. Extraction Methods
3.1 slice() - Extract a Portion
Returns a section of the string without modifying the original.
const text = 'JavaScript';
console.log(text.slice(0, 4)); // 'Java'
console.log(text.slice(4)); // 'Script'
console.log(text.slice(-6)); // 'Script' (from end)
console.log(text.slice(-6, -1)); // 'Scrip'
Syntax:
string.slice(startIndex, endIndex); // endIndex is exclusive
3.2 substring() - Extract Between Indices
Similar to slice(), but with different edge-case behavior.
const text = 'JavaScript';
console.log(text.substring(0, 4)); // 'Java'
console.log(text.substring(4, 0)); // 'Java' (swaps if start > end!)
slice() vs substring():
| Feature | slice() | substring() |
|---|---|---|
| Negative indices | ✅ Counts from end | ❌ Treats as 0 |
| start > end | Returns '' | Swaps the values |
| Recommended | ✅ Yes | Use slice() instead |
💡 tip[!TIP] Prefer
slice()oversubstring(). It's more predictable and supports negative indices.
3.3 charAt() & at() - Access Single Characters
const text = 'Hello';
// charAt()
console.log(text.charAt(0)); // 'H'
console.log(text.charAt(10)); // '' (empty string if out of bounds)
// at() — ES2022, supports negative indices
console.log(text.at(0)); // 'H'
console.log(text.at(-1)); // 'o' (last character)
console.log(text.at(-2)); // 'l'
// Bracket notation
console.log(text[0]); // 'H'
console.log(text[10]); // undefined
Comparison:
| Method | Out of bounds | Negative index | Return type |
|---|---|---|---|
charAt() | '' (empty string) | Not supported | string |
at() | undefined | ✅ Supported | string |
str[n] | undefined | Not supported | string |
4. Transformation Methods
4.1 Case Methods
const text = 'Hello World';
console.log(text.toUpperCase()); // 'HELLO WORLD'
console.log(text.toLowerCase()); // 'hello world'
function areEqual(str1, str2) {
return str1.toLowerCase() === str2.toLowerCase();
}
console.log(areEqual('Hello', 'hello')); // true
console.log(areEqual('ABC', 'abc')); // true
Title Case Converter:
function toTitleCase(str) {
return str
.toLowerCase()
.replace(/\b\w/g, char => char.toUpperCase());
}
console.log(toTitleCase('hello world from javascript'));
// 'Hello World From Javascript'
4.2 trim(), trimStart(), trimEnd() - Remove Whitespace
const input = ' Hello World ';
console.log(input.trim()); // 'Hello World'
console.log(input.trimStart()); // 'Hello World '
console.log(input.trimEnd()); // ' Hello World'
function sanitizeInput(value) {
return value
.trim()
.replace(/\s+/g, ' '); // Collapse multiple spaces
}
console.log(sanitizeInput(' John Doe ')); // 'John Doe'
4.3 padStart() & padEnd() - Pad Strings
const num = '5';
console.log(num.padStart(3, '0')); // '005'
console.log(num.padEnd(3, '0')); // '500'
Real-World Examples:
// Format time
const hours = '9';
const minutes = '5';
console.log(`${hours.padStart(2, '0')}:${minutes.padStart(2, '0')}`);
// '09:05'
// Mask credit card
function maskCard(cardNumber) {
const last4 = cardNumber.slice(-4);
return last4.padStart(cardNumber.length, '*');
}
console.log(maskCard('4532015112830366'));
// '************0366'
// Align output
const items = [['Apple', 1.5], ['Banana', 0.75], ['Cherry', 3.0]];
items.forEach(([name, price]) => {
console.log(`${name.padEnd(10)} $${price.toFixed(2)}`);
});
// Apple $1.50
// Banana $0.75
// Cherry $3.00
4.4 repeat() - Repeat a String
console.log('ha'.repeat(3)); // 'hahaha'
console.log('=-'.repeat(20)); // '=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-'
console.log('abc'.repeat(0)); // ''
function indent(text, level, spaces = 2) {
const padding = ' '.repeat(level * spaces);
return text
.split('\n')
.map(line => padding + line)
.join('\n');
}
console.log(indent('Hello\nWorld', 2));
// ' Hello'
// ' World'
5. Splitting & Joining
5.1 split() - Break String into Array
const csv = 'apple,banana,orange';
console.log(csv.split(',')); // ['apple', 'banana', 'orange']
console.log(csv.split(',', 2)); // ['apple', 'banana'] (limit)
Common Patterns:
// Split into characters
'hello'.split(''); // ['h', 'e', 'l', 'l', 'o']
// Split by whitespace
'Hello World'.split(' '); // ['Hello', 'World']
// Split by multiple delimiters (regex)
'one;two,three four'.split(/[;, ]/);
// ['one', 'two', 'three', 'four']
// Split by newlines
'line1\nline2\nline3'.split('\n');
// ['line1', 'line2', 'line3']
function parseQuery(queryString) {
return queryString
.replace('?', '')
.split('&')
.reduce((params, pair) => {
const [key, value] = pair.split('=');
params[decodeURIComponent(key)] = decodeURIComponent(value || '');
return params;
}, {});
}
console.log(parseQuery('?name=John&age=30&city=NYC'));
// { name: 'John', age: '30', city: 'NYC' }
5.2 concat() - Combine Strings
const first = 'Hello';
const second = 'World';
console.log(first.concat(' ', second)); // 'Hello World'
💡 tip[!TIP] Prefer template literals or the
+operator overconcat(). They're more readable and equally performant.
// ❌ Verbose
const message = 'Hello'.concat(' ', 'World');
// ✅ Preferred
const message = `Hello World`;
const message = 'Hello' + ' ' + 'World';
6. Template Literals
6.1 Basic Interpolation
const name = 'Alice';
const age = 30;
// String concatenation (old way)
const msg1 = 'My name is ' + name + ' and I am ' + age + ' years old.';
// Template literal (modern way)
const msg2 = `My name is ${name} and I am ${age} years old.`;
6.2 Multiline Strings
// ❌ Old way
const html1 = '<div>\n' +
' <h1>Title</h1>\n' +
' <p>Content</p>\n' +
'</div>';
// ✅ Template literals
const html2 = `
<div>
<h1>Title</h1>
<p>Content</p>
</div>`;
6.3 Expressions Inside Templates
const price = 19.99;
const tax = 0.08;
console.log(`Total: $${(price * (1 + tax)).toFixed(2)}`);
// 'Total: $21.59'
const items = ['apple', 'banana'];
console.log(`Count: ${items.length}`); // 'Count: 2'
console.log(`First: ${items[0].toUpperCase()}`); // 'First: APPLE'
6.4 Tagged Templates
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
return result + str + (values[i] ? `<mark>${values[i]}</mark>` : '');
}, '');
}
const name = 'Alice';
const role = 'admin';
console.log(highlight`User ${name} has ${role} access`);
// 'User <mark>Alice</mark> has <mark>admin</mark> access'
function sql(strings, ...values) {
return {
text: strings.join('$'),
values: values
};
}
const userId = "1; DROP TABLE users; --";
const query = sql`SELECT * FROM users WHERE id = ${userId}`;
// Values are safely parameterized, not interpolated into the query
7. String Comparison & Locale
7.1 localeCompare() - Language-Aware Sorting
const words = ['café', 'apple', 'banana'];
// Default sort (by code point)
console.log(words.sort());
// ['apple', 'banana', 'café']
// Locale-aware sort
console.log(words.sort((a, b) => a.localeCompare(b)));
// ['apple', 'banana', 'café']
With Options:
// Case-insensitive comparison
'a'.localeCompare('A', undefined, { sensitivity: 'base' }); // 0 (equal)
// Numeric sorting
'file2'.localeCompare('file10', undefined, { numeric: true }); // -1 (2 < 10)
'file10'.localeCompare('file2', undefined, { numeric: true }); // 1
8. String Conversion & Checking
8.1 String() vs .toString()
String(123); // '123'
String(true); // 'true'
String(null); // 'null'
String(undefined); // 'undefined'
(123).toString(); // '123'
// null.toString(); // ❌ TypeError!
// undefined.toString(); // ❌ TypeError!
💜 important[!IMPORTANT] Use
String()for safe conversion—it handlesnullandundefined..toString()throws on those values.
8.2 Number Base Conversion
const num = 255;
num.toString(2); // '11111111' (binary)
num.toString(8); // '377' (octal)
num.toString(16); // 'ff' (hexadecimal)
// Parsing back
parseInt('ff', 16); // 255
parseInt('11111111', 2); // 255
9. Common Patterns & Recipes
9.1 Reverse a String
function reverseString(str) {
return str.split('').reverse().join('');
}
console.log(reverseString('hello')); // 'olleh'
// ES6 spread syntax
const reversed = [...'hello'].reverse().join('');
9.2 Check Palindrome
function isPalindrome(str) {
const clean = str.toLowerCase().replace(/[^a-z0-9]/g, '');
return clean === clean.split('').reverse().join('');
}
console.log(isPalindrome('racecar')); // true
console.log(isPalindrome('A man, a plan, a canal: Panama')); // true
console.log(isPalindrome('hello')); // false
9.3 Count Occurrences
function countOccurrences(str, char) {
return str.split(char).length - 1;
}
console.log(countOccurrences('hello world', 'l')); // 3
// Regex version (more flexible)
function countPattern(str, pattern) {
return (str.match(new RegExp(pattern, 'g')) || []).length;
}
console.log(countPattern('banana', 'an')); // 2
9.4 Truncate String
function truncate(str, maxLength, suffix = '...') {
if (str.length <= maxLength) return str;
return str.slice(0, maxLength - suffix.length) + suffix;
}
console.log(truncate('JavaScript is awesome!', 15));
// 'JavaScript i...'
9.5 Capitalize First Letter
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
console.log(capitalize('hello')); // 'Hello'
10. Quick Interview Q&A
| Question | Answer |
|---|---|
| Strings mutable or immutable? | Immutable. All methods return a new string. |
| slice() vs substring()? | slice() supports negative indices; substring() swaps args if start > end. Prefer slice(). |
| includes() vs indexOf()? | includes() returns boolean; indexOf() returns position. Use includes() for existence checks. |
| replace() vs replaceAll()? | replace() replaces first match only; replaceAll() replaces all (ES2021). |
| How to reverse a string? | str.split('').reverse().join('') — no built-in method exists. |
| Template literal vs concatenation? | Template literals are more readable, support multiline, and allow expressions via ${}. |
| match() vs matchAll()? | match() with g flag loses capture groups. matchAll() preserves them as an iterator. |
Conclusion
JavaScript string methods are essential for any developer working with text processing, data formatting, user input handling, or template generation. Mastering them means:
- Search: Know
includes()for existence,indexOf()for position,search()for regex - Extract: Use
slice()as your go-to extraction tool - Transform: Leverage
trim(), case methods, andpadStart()/padEnd()for formatting - Pattern Match: Use
replaceAll()for simple replacements,matchAll()for detailed regex work - Template Literals: Always prefer them over string concatenation
The key insight is that strings are immutable—every operation creates a new string. Understanding this prevents bugs and helps you write efficient, predictable code.
Happy coding! 🚀
🧠 Test Your Knowledge
Now that you've learned the concepts, let's see if you can apply them! Take this quick quiz to test your understanding.