JavaScript Strings
Master string immutability, character indexing with at(), template literals, slice vs substring, search methods, and modern text transformations.
1. What is a String?
A string is just text wrapped in quotes (like 'hello' or "world"). You use strings to store names, messages, URLs, or any piece of written information.
💡 Strings are Read-Only (Immutable)
In JavaScript, strings are read-only. You can read any character by its index, but you cannot change an individual letter directly with str[0] = "J". When you use methods like .toUpperCase(), JavaScript always creates and gives you a brand new string.
let tech = "react";
// ❌ In-place mutation has no effect
tech[0] = "R";
console.log(tech); // "react" (unchanged!)
// ✅ Create a new string by calling methods or reassigning
tech = tech.toUpperCase();
console.log(tech); // "REACT"
react REACT
2. Accessing Characters: `[]` vs `charAt()` vs `at()`
JavaScript provides three primary ways to access individual characters by their zero-based index:
Bracket Notation `str[i]` & `charAt()`
Traditional character access from index 0 up to length - 1.
str[99]out-of-bounds returnsundefinedstr.charAt(99)out-of-bounds returns""- Cannot accept negative indices easily
const name = "Node";
console.log(name[0]); // "N"
console.log(name.charAt(1)); // "o"
console.log(name[99]); // undefined
Modern `str.at()` (ES2022 ✅)
Clean relative indexing that natively supports negative numbers from the end.
.at(-1)retrieves the last character.at(-2)retrieves the second to last- No more verbose
str[str.length - 1]
const name = "Node";
console.log(name.at(0)); // "N"
console.log(name.at(-1)); // "e" (last char)
console.log(name.at(-2)); // "d"
3. Template Literals & Interpolation
Enclosed by backticks (` `), template literals solve multiline string concatenation and dynamic expression embedding:
const product = "MacBook Pro";
const price = 1999;
const tax = 0.08;
// 1. Multiline & Expression Interpolation
const invoice = `Order Details:
- Product: ${product}
- Subtotal: $${price}
- Total: $${(price * (1 + tax)).toFixed(2)}`;
console.log(invoice);
Order Details: - Product: MacBook Pro - Subtotal: $1999 - Total: $2158.92
4. Extracting Substrings: `slice()` vs `substring()`
While both extract portions of a string without modifying the original, their handling of negative indices and argument ordering differs:
`str.slice(start, end)` (Recommended ✅)
Extracts up to, but not including, index end.
- Supports negative indices (counts from end)
- Does not swap start and end
- Matches
Array.prototype.slice
const text = "JavaScript";
console.log(text.slice(0, 4)); // "Java"
console.log(text.slice(-6)); // "Script"
console.log(text.slice(4, 0)); // "" (empty)
`str.substring(start, end)`
Legacy substring extraction method.
- Swaps arguments if
start > end - Treats negative values as
0 - Avoid using in modern code
const text = "JavaScript";
console.log(text.substring(0, 4)); // "Java"
console.log(text.substring(4, 0)); // "Java" (swapped!)
console.log(text.substring(-4)); // "JavaScript"
⚠️ Deprecation Warning: Avoid `substr()`
str.substr(start, length) is a deprecated legacy method. Always use str.slice(start, end) in modern JavaScript development.
5. Searching & Inspecting Strings
Modern JavaScript provides intuitive boolean and index-based searching methods:
const file = "user-avatar.png";
// 1. Boolean check methods (ES6+)
console.log(file.includes("avatar")); // true
console.log(file.startsWith("user")); // true
console.log(file.endsWith(".png")); // true
console.log(file.endsWith(".jpg")); // false
// 2. Index finders
console.log(file.indexOf("avatar")); // 5 (starting index)
console.log(file.indexOf("profile")); // -1 (not found)
console.log(file.lastIndexOf("-")); // 4 (last occurrence)
true true true false 5 -1 4
💡 The Index 0 Truthy/Falsy Pitfall
When checking if a substring exists, avoid writing if (str.indexOf("text")). If "text" is found at index 0, JavaScript coerces 0 to false! Always use str.includes("text") or compare explicitly with str.indexOf("text") !== -1.
6. Transforming & Formatting Strings
Common transformations used for input sanitization, UI formatting, and data normalization:
// 1. Trimming Whitespace
const raw = " hello@domain.com \n ";
console.log(raw.trim()); // "hello@domain.com"
console.log(raw.trimStart()); // "hello@domain.com \n "
// 2. Case Normalization
const role = "aDmIn";
console.log(role.toLowerCase()); // "admin"
console.log(role.toUpperCase()); // "ADMIN"
// 3. String Padding & Repeating
console.log("5".padStart(3, "0")); // "005" (zero-fill formatted numbers)
console.log("42".padEnd(6, ".")); // "42...."
console.log("La ".repeat(3)); // "La La La "
// 4. replace() vs replaceAll()
const promptText = "cats and cats";
console.log(promptText.replace("cats", "dogs")); // "dogs and cats" (First match only)
console.log(promptText.replaceAll("cats", "dogs")); // "dogs and dogs" (All matches)
hello@domain.com admin ADMIN 005 42.... La La La dogs and cats dogs and dogs
7. The String-Array Bridge: `split()` and `join()`
Converting strings to arrays with .split() and recombining them with .join() is one of the most essential patterns for text parsing, slug generation, and data cleaning:
// 1. String to Words Array
const heading = "Master Modern JavaScript Today";
const words = heading.split(" ");
console.log(words); // ["Master", "Modern", "JavaScript", "Today"]
// 2. Generating a URL Slug
const slug = words.map(w => w.toLowerCase()).join("-");
console.log(slug); // "master-modern-javascript-today"
// 3. Reversing a String
const reversed = "frontend".split("").reverse().join("");
console.log(reversed); // "dnetnorf"
// 4. Extracting CSV Values
const csvRow = "Alex,24,Engineer,London";
const [userName, age, roleTitle, city] = csvRow.split(",");
console.log(`${userName} is a ${roleTitle} in ${city}.`);
[ 'Master', 'Modern', 'JavaScript', 'Today' ] master-modern-javascript-today dnetnorf Alex is a Engineer in London.
8. Quick Reference: Common String Methods
| Method | Description | Example | Result |
|---|---|---|---|
.slice(start, end) |
Extracts portion by indices (supports negative) | "code".slice(1, 3) |
"od" |
.at(index) |
Character at index (supports negative) | "code".at(-1) |
"e" |
.includes(search) |
Checks if substring exists | "api".includes("p") |
true |
.startsWith(prefix) |
Checks beginning of string | "https://".startsWith("http") |
true |
.trim() |
Removes leading and trailing whitespace | " hi ".trim() |
"hi" |
.padStart(len, char) |
Pads start to target length | "7".padStart(3, "0") |
"007" |
.replaceAll(sub, new) |
Replaces all occurrences | "a-b-c".replaceAll("-", ":") |
"a:b:c" |
.split(separator) |
Splits string into array | "a,b".split(",") |
["a", "b"] |
9. Strings Interview Deck
Test your understanding of string immutability, index slice bounds, search methods, and modern replace utilities:
10. Practice Challenges
🎯 Coding Challenge: String Processing & Sanitization
1. Clean rawInput by trimming whitespace and verify if it starts with "https://".
2. Split the URL path segments and retrieve the user ID (4590) using modern .at().
3. Mask the credit card string "1234567890123456" to show only the last 4 digits (e.g. "************3456") using .slice() and .padStart().