String Basics
Strings can be written with single quotes, double quotes, or backticks. They are zero-indexed sequences of characters.
const a = 'single quotes';
const b = "double quotes";
const c = `backtick (template literal)`;
// Length
console.log("hello".length); // 5
// Character access (zero-indexed)
const str = "JavaScript";
console.log(str[0]); // "J"
console.log(str[4]); // "S"
console.log(str.at(-1)); // "t" (last char - ES2022)
console.log(str.at(-2)); // "p"
// Escape sequences
const quote = "She said \"hello\""; // escaped double quote
const path = 'C:\\Users\\Alice'; // escaped backslash
const newline = "Line 1\nLine 2"; // \n = newline
const tab = "col1\tcol2"; // \t = tab
// String concatenation
const first = "John";
const last = "Doe";
console.log(first + " " + last); // "John Doe"
console.log(first.concat(" ", last)); // "John Doe"
Template Literals
Template literals (backticks) support interpolation, multiline strings, and tagged templates. Prefer them over concatenation.
const name = "Alice";
const age = 30;
// Interpolation - any expression inside ${}
console.log(`Hello, ${name}!`); // "Hello, Alice!"
console.log(`${name} is ${age} years old.`); // "Alice is 30 years old."
console.log(`2 + 2 = ${2 + 2}`); // "2 + 2 = 4"
console.log(`Upper: ${name.toUpperCase()}`); // "Upper: ALICE"
// Ternary inside template
const isAdmin = true;
console.log(`Role: ${isAdmin ? "Admin" : "User"}`); // "Role: Admin"
// Multiline strings (preserves actual newlines)
const html = `
<div class="card">
<h2>${name}</h2>
<p>Age: ${age}</p>
</div>
`;
// Nested template literals
const items = ["apple", "banana", "cherry"];
const list = `Items: ${items.map(item => `[${item}]`).join(", ")}`;
console.log(list); // "Items: [apple], [banana], [cherry]"
Essential String Methods
The most commonly used methods for extracting and modifying substrings:
const str = "Hello, World!";
// slice(start, end) - preferred substring method
console.log(str.slice(7)); // "World!" (from index 7 to end)
console.log(str.slice(7, 12)); // "World" (index 7 up to, not including, 12)
console.log(str.slice(-6)); // "World!" (from 6th from end)
console.log(str.slice(-6, -1)); // "World" (negative end)
// toUpperCase / toLowerCase
console.log(str.toUpperCase()); // "HELLO, WORLD!"
console.log(str.toLowerCase()); // "hello, world!"
// trim - remove leading/trailing whitespace
const padded = " hello ";
console.log(padded.trim()); // "hello"
console.log(padded.trimStart()); // "hello "
console.log(padded.trimEnd()); // " hello"
// repeat
console.log("ha".repeat(3)); // "hahaha"
// padStart / padEnd - pad to a minimum length
console.log("5".padStart(3, "0")); // "005" (useful for IDs, time formatting)
console.log("hi".padEnd(10, ".")); // "hi........"
Search and Test Methods
const text = "JavaScript is awesome and JavaScript is fun";
// includes - boolean check (preferred for existence check)
console.log(text.includes("awesome")); // true
console.log(text.includes("python")); // false
console.log(text.includes("Java", 15)); // true (search from index 15)
// startsWith / endsWith
console.log(text.startsWith("Java")); // true
console.log(text.endsWith("fun")); // true
console.log(text.startsWith("awesome", 14)); // true (from index 14)
// indexOf / lastIndexOf - return position or -1
console.log(text.indexOf("JavaScript")); // 0 (first occurrence)
console.log(text.lastIndexOf("JavaScript")); // 26 (last occurrence)
console.log(text.indexOf("Python")); // -1 (not found)
// search - like indexOf but accepts RegExp
console.log(text.search(/java/i)); // 0 (case-insensitive match)
// match - extract matches
const matches = text.match(/JavaScript/g); // global flag = all matches
console.log(matches); // ["JavaScript", "JavaScript"]
const dateStr = "2024-01-15";
const dateParts = dateStr.match(/(\d{4})-(\d{2})-(\d{2})/);
console.log(dateParts[1]); // "2024"
console.log(dateParts[2]); // "01"
Transform and Format
// replace - replaces first match
const str = "cats are great, cats are cute";
console.log(str.replace("cats", "dogs")); // "dogs are great, cats are cute"
// replaceAll - replaces all matches (ES2021)
console.log(str.replaceAll("cats", "dogs")); // "dogs are great, dogs are cute"
// replace with function
const result = "hello world".replace(/\b\w/g, char => char.toUpperCase());
console.log(result); // "Hello World" (title case)
// String.fromCharCode / charCodeAt
console.log("A".charCodeAt(0)); // 65
console.log(String.fromCharCode(65)); // "A"
// Number formatting with strings
const price = 1234567.89;
console.log(price.toFixed(2)); // "1234567.89"
console.log(price.toLocaleString("en-US")); // "1,234,567.89"
// at() method (ES2022) - cleaner than length-based access
const arr = "Hello";
console.log(arr.at(0)); // "H"
console.log(arr.at(-1)); // "o"
Split and Join
split() converts a string to an array. join() (on arrays)
converts back. They are inverses of each other.
// split - string to array
const csv = "apple,banana,cherry";
const fruits = csv.split(",");
console.log(fruits); // ["apple", "banana", "cherry"]
const words = "hello world foo".split(" ");
console.log(words); // ["hello", "world", "foo"]
const chars = "abc".split("");
console.log(chars); // ["a", "b", "c"]
// split with limit
console.log("a,b,c,d".split(",", 2)); // ["a", "b"]
// join - array to string
console.log(fruits.join(" - ")); // "apple - banana - cherry"
console.log(fruits.join("")); // "applebananacherry"
console.log(fruits.join()); // "apple,banana,cherry" (default comma)
// Common pattern: reverse a string
const reversed = "hello".split("").reverse().join("");
console.log(reversed); // "olleh"
// Practical: parse a URL path
const path = "/api/users/42";
const parts = path.split("/").filter(Boolean); // filter removes empty strings
console.log(parts); // ["api", "users", "42"]
String Immutability
Strings in JavaScript are immutable primitives. Every string method returns a new string. The original is never modified.
let greeting = "hello";
// Attempting to modify in place - silently does nothing
greeting[0] = "H";
console.log(greeting); // "hello" - unchanged!
// All methods return new strings
const upper = greeting.toUpperCase();
console.log(greeting); // "hello" - original unchanged
console.log(upper); // "HELLO" - new string
// You must reassign if you want the changed value
greeting = greeting.toUpperCase();
console.log(greeting); // "HELLO"
// Chaining methods (each returns a new string)
const cleaned = " Hello, World! "
.trim()
.toLowerCase()
.replace("hello", "hi");
console.log(cleaned); // "hi, world!"
Quick Reference Table
| Method | What it does | Returns |
|---|---|---|
str.length | Number of characters | number |
str.at(i) | Character at index (supports negative) | string |
str.slice(s, e) | Extract substring | string |
str.toUpperCase() | Uppercase copy | string |
str.toLowerCase() | Lowercase copy | string |
str.trim() | Remove whitespace at both ends | string |
str.includes(sub) | Does string contain sub? | boolean |
str.startsWith(sub) | Does string start with sub? | boolean |
str.endsWith(sub) | Does string end with sub? | boolean |
str.indexOf(sub) | First index of sub (-1 if absent) | number |
str.replace(a, b) | Replace first match of a with b | string |
str.replaceAll(a, b) | Replace all matches of a with b | string |
str.split(sep) | Split into array | array |
str.repeat(n) | Repeat string n times | string |
str.padStart(n, p) | Pad start to length n with p | string |