Skip to main content

String Methods

Strings in JavaScript

Strings in JavaScript are immutable — every string method returns a new string; it never modifies the original. This is important to remember: always use the return value.

const str = "hello";
str.toUpperCase(); // "HELLO"
console.log(str); // "hello" — unchanged

Finding and Checking

includes()

Check if a string contains a substring:

"hello world".includes("world"); // true
"hello world".includes("xyz"); // false
"hello world".includes("o", 5); // true (start search from index 5)

startsWith() / endsWith()

"hello world".startsWith("hello"); // true
"hello world".endsWith("world"); // true
"hello world".startsWith("world"); // false

// With position
"hello world".startsWith("world", 6); // true (starts at index 6)

indexOf() / lastIndexOf()

Returns the index of first/last occurrence, or -1 if not found:

"banana".indexOf("a"); // 1
"banana".lastIndexOf("a"); // 5
"banana".indexOf("z"); // -1

// Check existence (prefer includes() for readability)
if (str.indexOf("hello") !== -1) { ... }

Like indexOf but accepts a regex:

"hello 123".search(/\d+/); // 6 (index of first digit sequence)
"hello".search(/\d+/); // -1

Extracting

slice(start, end)

Extract a portion of a string. Negative indices count from the end:

"hello world".slice(0, 5); // "hello"
"hello world".slice(6); // "world"
"hello world".slice(-5); // "world"
"hello world".slice(0, -6); // "hello"

substring(start, end)

Similar to slice but doesn't support negative indices:

"hello world".substring(0, 5); // "hello"
"hello world".substring(6); // "world"
tip
slice vs substring

Prefer slice — it handles negative indices (counting from the end) which is often useful. substring swaps arguments if start > end; slice returns an empty string instead.

charAt(index) / bracket notation

"hello"[0]; // "h"
"hello".charAt(1); // "e"
"hello".charAt(99); // "" (empty string, no error)

at(index)

Modern alternative — supports negative indices:

"hello".at(0); // "h"
"hello".at(-1); // "o" (last character)
"hello".at(-2); // "l"

Transforming

toUpperCase() / toLowerCase()

"Hello World".toUpperCase(); // "HELLO WORLD"
"Hello World".toLowerCase(); // "hello world"

// Useful for case-insensitive comparison
"Email".toLowerCase() === "email" // true

trim() / trimStart() / trimEnd()

Remove whitespace from one or both ends:

" hello ".trim(); // "hello"
" hello ".trimStart(); // "hello "
" hello ".trimEnd(); // " hello"

Always trim user input before storing or comparing:

const email = req.body.email.trim().toLowerCase();

replace() / replaceAll()

"hello world".replace("world", "there"); // "hello there"
"aabbcc".replace("b", "x"); // "aaxbcc" — only first match!
"aabbcc".replaceAll("b", "x"); // "aaxxcc" — all matches

// With regex
"Hello World".replace(/[A-Z]/g, "-"); // "-ello -orld"
"2024-01-15".replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1"); // "15/01/2024"

repeat()

"ha".repeat(3); // "hahaha"
"-".repeat(20); // "--------------------"

padStart() / padEnd()

Pad a string to a minimum length:

"5".padStart(3, "0"); // "005"
"42".padStart(5, "0"); // "00042"
"hi".padEnd(5, "."); // "hi..."

// Common use: formatting numbers
const formatId = (id) => String(id).padStart(6, "0");
formatId(42); // "000042"

Splitting and Joining

split(separator)

Convert a string into an array:

"a,b,c".split(","); // ["a", "b", "c"]
"hello".split(""); // ["h", "e", "l", "l", "o"]
"one two three".split(" "); // ["one", "two", "three"]
"hello".split("", 3); // ["h", "e", "l"] — limit results

Array.join() — reverse of split

["a", "b", "c"].join(","); // "a,b,c"
["hello", "world"].join(" "); // "hello world"
["2024", "01", "15"].join("-"); // "2024-01-15"

String ↔ Number Conversion

// String to number
Number("42"); // 42
parseInt("42px"); // 42 — stops at non-numeric character
parseFloat("3.14"); // 3.14
+"42"; // 42 — unary plus (terse but less readable)

// Number to string
String(42); // "42"
(42).toString(); // "42"
(255).toString(16); // "ff" — hex representation
(42).toString(2); // "101010" — binary

Template Literals (Quick Reminder)

For multi-line strings and embedding expressions:

const name = "Rizwan";
const age = 25;

const message = `Hello, ${name}!
You are ${age} years old.
Next year you'll be ${age + 1}.`;

Much cleaner than string concatenation, especially for building URLs or query strings:

const url = `${BASE_URL}/api/users/${userId}/posts?page=${page}&limit=${limit}`;

Common Patterns

// Capitalize first letter
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
capitalize("hello"); // "Hello"

// Convert camelCase to kebab-case
const toKebab = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
toKebab("myVariableName"); // "my-variable-name"

// Truncate with ellipsis
const truncate = (str, max) =>
str.length > max ? str.slice(0, max - 3) + "..." : str;
truncate("Hello World", 8); // "Hello..."

// Count occurrences
const countOccurrences = (str, char) =>
str.split(char).length - 1;
countOccurrences("banana", "a"); // 3

// Check if palindrome
const isPalindrome = (str) => {
const clean = str.toLowerCase().replace(/[^a-z0-9]/g, "");
return clean === clean.split("").reverse().join("");
};
isPalindrome("racecar"); // true
isPalindrome("A man a plan a canal Panama"); // true

Quick Reference

MethodPurposeReturns
includes(str)Does it contain substring?boolean
startsWith(str)Does it start with?boolean
endsWith(str)Does it end with?boolean
indexOf(str)First index of substringnumber
slice(start, end)Extract portionstring
at(index)Character at index (supports -1)string
toUpperCase()All capsstring
toLowerCase()All lowercasestring
trim()Remove surrounding whitespacestring
replace(a, b)Replace first matchstring
replaceAll(a, b)Replace all matchesstring
split(sep)Split into arrayarray
padStart(len, ch)Pad from leftstring
repeat(n)Repeat n timesstring