JavaScript Strings and Template Literals

1. String Creation and String Literals

Type Syntax Description Example
Single Quotes 'string' Basic string literal; escape ' as \' 'Hello world'
Double Quotes "string" Identical to single quotes; escape " as \" "Hello world"
Template Literal `string` Backticks; supports interpolation, multiline, and tag functions `Hello ${name}`
String Constructor String(value) Convert to string; returns primitive (without new) String(123) // "123"
String Object new String(value) Creates String object (wrapper); avoid - use primitives new String("hi")
Escape Sequences \n \t \\ \' \" Special characters: newline, tab, backslash, quotes 'Line 1\nLine 2'
Unicode Escape \uXXXX 4-digit hex Unicode code point (BMP only) '\u0041' // "A"
Unicode Code Point \u{X...} 1-6 hex digits; supports full Unicode range (including astral) '\u{1F600}' // "šŸ˜€"
Hex Escape \xXX 2-digit hex byte value (0x00-0xFF) '\x41' // "A"
Raw String ES2015 String.raw`...` Template literal without escape processing String.raw`\n` // "\\n"

Example: String creation patterns

// Literal syntax (preferred)
const single = 'Hello';
const double = "World";
const template = `Hello ${name}`;

// String constructor (type conversion)
String(123); // "123"
String(true); // "true"
String(null); // "null"
String({a: 1}); // "[object Object]"

// Avoid String object (wrapper)
const bad = new String("text"); // typeof bad === "object" āŒ
const good = "text"; // typeof good === "string" āœ“

// Escape sequences
'Line 1\nLine 2'; // newline
'Tab\tseparated'; // tab
'She said "hi"'; // double quotes in single
"It's okay"; // single quote in double
'Can\'t escape'; // escaped single quote

// More escape sequences
'C:\\Users\\name'; // backslashes
'First\x20Second'; // space using hex
'\u00A9 2025'; // Ā© 2025
'\u{1F4A9}'; // šŸ’© (requires code point syntax)

// Multiline strings
const multi = `Line 1
Line 2
Line 3`; // preserves newlines

const legacy = 'Line 1\n' +
               'Line 2\n' +
               'Line 3'; // old way

// Raw strings (no escape processing)
String.raw`C:\Users\name`; // "C:\\Users\\name"
String.raw`\n\t`; // "\\n\\t" (literal backslashes)

// Empty and whitespace
const empty = '';
const space = ' ';
const whitespace = '   \t\n   ';

// Immutability
const str = 'hello';
str[0] = 'H'; // No effect - strings are immutable
str.toUpperCase(); // Returns "HELLO", str unchanged
Note: Strings are immutable primitives. Use single/double quotes for simple strings; template literals for interpolation/multiline. Avoid new String() wrapper objects.

2. String Methods (slice, substring, charAt, indexOf, replace, split)

Method Syntax Description Returns
length str.length Number of UTF-16 code units (not characters!); astral chars count as 2 Number
charAt() str.charAt(index) Character at index; returns empty string if out of bounds String
charCodeAt() str.charCodeAt(index) UTF-16 code unit (0-65535); NaN if out of bounds Number
codePointAt() str.codePointAt(index) Full Unicode code point; handles astral characters correctly Number
at() ES2022 str.at(index) Character at index; negative indices from end; undefined if out of bounds String | undefined
concat() str.concat(str2, ...) Join strings; prefer + or template literals for readability String
slice() str.slice(start, end) Extract substring; negative indices from end; preferred method String
substring() str.substring(start, end) Like slice but swaps args if start > end; no negative indices String
substr() DEPRECATED str.substr(start, length) Extract by length; deprecated - use slice() instead String
toUpperCase() str.toUpperCase() Convert to uppercase; locale-independent String
toLowerCase() str.toLowerCase() Convert to lowercase; locale-independent String
toLocaleUpperCase() str.toLocaleUpperCase(locale) Locale-aware uppercase (e.g., Turkish İ/I) String
toLocaleLowerCase() str.toLocaleLowerCase(locale) Locale-aware lowercase String
trim() str.trim() Remove whitespace from both ends String
trimStart() / trimLeft() str.trimStart() Remove whitespace from start only String
trimEnd() / trimRight() str.trimEnd() Remove whitespace from end only String
padStart() ES2017 str.padStart(length, padStr) Pad to length from start; default space String
padEnd() ES2017 str.padEnd(length, padStr) Pad to length from end; default space String
repeat() str.repeat(count) Repeat string count times; count must be non-negative integer String

Example: String manipulation methods

const str = 'Hello World';

// Access characters
str.charAt(0); // "H"
str[0]; // "H" (bracket notation)
str.at(0); // "H"
str.at(-1); // "d" (last character)
str.at(-2); // "l" (second to last)

// Character codes
str.charCodeAt(0); // 72 (UTF-16 code unit)
str.codePointAt(0); // 72 (Unicode code point)

// Emoji handling
const emoji = 'šŸ˜€';
emoji.length; // 2 āŒ (surrogate pair)
emoji.codePointAt(0); // 128512 āœ“
emoji.charCodeAt(0); // 55357 āŒ (high surrogate only)

// Substrings
str.slice(0, 5); // "Hello"
str.slice(6); // "World"
str.slice(-5); // "World" (last 5)
str.slice(-5, -1); // "Worl"

str.substring(0, 5); // "Hello" (same as slice)
str.substring(5, 0); // "Hello" (swaps args!)

// Case conversion
'JavaScript'.toUpperCase(); // "JAVASCRIPT"
'JavaScript'.toLowerCase(); // "javascript"

// Turkish locale example
'i'.toLocaleUpperCase('tr'); // "İ" (dotted capital I)
'I'.toLocaleLowerCase('tr'); // "ı" (dotless small i)

// Whitespace removal
'  hello  '.trim(); // "hello"
'  hello  '.trimStart(); // "hello  "
'  hello  '.trimEnd(); // "  hello"

// Padding
'5'.padStart(3, '0'); // "005"
'123'.padStart(5, '0'); // "00123"
'hello'.padEnd(10, '.'); // "hello....."

const cardNum = '1234';
cardNum.padStart(16, '*'); // "************1234"

// Repeat
'*'.repeat(10); // "**********"
'abc'.repeat(3); // "abcabcabc"

// Concatenation
'Hello'.concat(' ', 'World'); // "Hello World"
'a' + 'b' + 'c'; // "abc" (preferred)

// Chaining
const result = '  HELLO  '
    .trim()
    .toLowerCase()
    .repeat(2)
    .padStart(15, '.');
// "...hellohello"
Note: Use slice() over substring() for consistency with arrays. Avoid deprecated substr(). Remember length counts UTF-16 code units, not characters.

3. Template Literals (``) and Tag Functions

Feature Syntax Description Example
Template Literal `text` Backticks; supports interpolation and multiline `Hello ${name}`
Interpolation ${expression} Embed any expression; converted to string via ToString `Sum: ${a + b}`
Multiline `line1\nline2` Preserves actual newlines and indentation `Line 1\nLine 2`
Tagged Template tag`template` Function processes template; receives strings and values separately html`<div>${text}</div>`
String.raw String.raw`text` Built-in tag that returns raw string (no escape processing) String.raw`\n` // "\\n"
Tag Function Signature Receives strings array and interpolated values
Parameters function tag(strings, ...values)
strings Array of string literals; has .raw property for unprocessed strings
...values Rest parameter with all interpolated expression results

Example: Template literals and tag functions

// Basic interpolation
const name = 'Alice';
const age = 25;
const msg = `Hello ${name}, you are ${age} years old`;
// "Hello Alice, you are 25 years old"

// Expressions
const a = 10, b = 20;
`Sum: ${a + b}`; // "Sum: 30"
`Comparison: ${a > b ? 'a' : 'b'}`; // "Comparison: b"
`Array: ${[1, 2, 3].join(', ')}`; // "Array: 1, 2, 3"

// Multiline
const html = `
  <div class="card">
    <h2>${name}</h2>
    <p>Age: ${age}</p>
  </div>
`; // Preserves indentation and newlines

// Nesting
`Outer ${`Inner ${1 + 1}`} text`; // "Outer Inner 2 text"

// String.raw - no escape processing
String.raw`C:\Users\name`; // "C:\\Users\\name"
String.raw`Line 1\nLine 2`; // "Line 1\\nLine 2"

// Custom tag function - basic
function upper(strings, ...values) {
    let result = '';
    strings.forEach((str, i) => {
        result += str;
        if (i < values.length) {
            result += String(values[i]).toUpperCase();
        }
    });
    return result;
}

upper`Hello ${name}, age ${age}`;
// "Hello ALICE, age 25"

// Tag function - HTML escaping
function html(strings, ...values) {
    return strings.reduce((result, str, i) => {
        const value = values[i] || '';
        const escaped = String(value)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;');
        return result + str + escaped;
    }, '');
}

const userInput = '<script>alert("xss")</script>';
html`<div>${userInput}</div>`;
// "<div>&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;</div>"

// Tag function - SQL (parameterized queries)
function sql(strings, ...values) {
    return {
        query: strings.join('?'),
        params: values
    };
}

const userId = 123;
const query = sql`SELECT * FROM users WHERE id = ${userId}`;
// {query: "SELECT * FROM users WHERE id = ?", params: [123]}

// Tag function - i18n translation
function t(strings, ...values) {
    const key = strings.join('{}');
    // Look up translation for key
    return translate(key, values);
}

t`Welcome ${name}!`; // Translates "Welcome {}!" with name

// Access raw strings
function logger(strings, ...values) {
    console.log('Processed:', strings);
    console.log('Raw:', strings.raw);
    console.log('Values:', values);
}

logger`Line 1\nLine 2`;
// Processed: ["Line 1
// Line 2"]
// Raw: ["Line 1\\nLine 2"]
// Values: []

// Empty interpolations
`a${null}b`; // "anullb"
`a${undefined}b`; // "aundefinedb"
`a${''}b`; // "ab"
Note: Tagged templates enable custom string processing (HTML escaping, i18n, SQL, styling). The strings.raw property provides unprocessed strings. All interpolated values are converted to strings.

4. String Interpolation (${}) and Expression Embedding

Pattern Syntax Description Example
Variable ${variable} Insert variable value; converts to string `Hello ${name}`
Expression ${expr} Any valid expression; evaluated and converted to string `Sum: ${a + b}`
Function Call ${fn()} Call function and insert return value `Time: ${getTime()}`
Ternary ${cond ? a : b} Conditional expressions inline `${online ? '🟢' : 'šŸ”“'}`
Logical AND ${cond && value} Short-circuit conditional rendering; false becomes "false" string `${hasError && errorMsg}`
Logical OR ${val || default} Fallback value; beware of 0, '', false `${name || 'Guest'}`
Nullish Coalescing ${val ?? default} Fallback only for null/undefined; preserves 0, '', false `${count ?? 0}`
Array Method ${arr.method()} Array operations inline `Items: ${arr.join(', ')}`
Object Property ${obj.prop} Access nested properties `Name: ${user.name}`
Nested Template ${`inner ${val}`} Template literals can be nested `Outer ${`inner ${x}`}`

Example: String interpolation patterns

const user = {name: 'Alice', age: 25, online: true};
const items = ['apple', 'banana', 'orange'];
const count = 0;

// Basic variable
`Username: ${user.name}`; // "Username: Alice"

// Arithmetic expressions
`Total: ${(99.99 * 1.1).toFixed(2)}`; // "Total: $109.99"
`Progress: ${(completed / total * 100).toFixed(1)}%`;

// Function calls
`Generated at ${new Date().toISOString()}`;
`Random: ${Math.random().toFixed(4)}`;

// Ternary operator
`Status: ${user.online ? '🟢 Online' : 'šŸ”“ Offline'}`;
`You have ${count === 0 ? 'no' : count} items`;

// Logical AND (conditional content)
`${user.admin && 'Admin Panel'}`;
// If admin: "Admin Panel", else: "false" āŒ

// Better: use ternary for boolean
`${user.admin ? 'Admin Panel' : ''}`;
// If admin: "Admin Panel", else: ""

// Logical OR (fallback)
`Hello ${user.nickname || user.name}`;
`Count: ${count || 'N/A'}`; // āŒ 0 becomes 'N/A'!

// Nullish coalescing (better fallback)
`Count: ${count ?? 'N/A'}`; // āœ“ 0 stays 0
`Name: ${user.name ?? 'Anonymous'}`;

// Array methods
`Items: ${items.join(', ')}`; // "Items: apple, banana, orange"
`Count: ${items.length}`;
`First: ${items[0]}`;

// Array rendering with map
`<ul>${items.map(item => `<li>${item}</li>`).join('')}</ul>`;
// "<ul><li>apple</li><li>banana</li><li>orange</li></ul>"

// Object methods
`User: ${JSON.stringify(user)}`;
`Keys: ${Object.keys(user).join(', ')}`;

// Nested templates
const className = `btn ${user.online ? 'btn-success' : 'btn-danger'}`;
`<button class="${className}">${user.name}</button>`;

// Complex expressions
const price = 99.99;
const discount = 0.15;
const tax = 0.08;
`Final: ${(price * (1 - discount) * (1 + tax)).toFixed(2)}`;

// Method chaining
`Result: ${str.trim().toLowerCase().split(' ').join('-')}`;

// Type coercion
`Number: ${123}`; // "Number: 123"
`Boolean: ${true}`; // "Boolean: true"
`Null: ${null}`; // "Null: null"
`Undefined: ${undefined}`; // "Undefined: undefined"
`Object: ${{}}`; // "Object: [object Object]"
`Array: ${[1, 2]}`; // "Array: 1,2"

// Multi-line with interpolation
const html = `
  <div class="user-card ${user.online ? 'online' : 'offline'}">
    <h2>${user.name}</h2>
    <p>Age: ${user.age}</p>
    <p>Status: ${user.online ? '🟢' : 'šŸ”“'}</p>
  </div>
`;

// Escaping interpolation
const literal = String.raw`Not interpolated: \${variable}`;
// "Not interpolated: ${variable}"
Warning: Logical AND ${cond && val} converts false to "false" string. Use ternary ${cond ? val : ''} for conditional rendering. Prefer ?? over || for fallbacks.

5. Unicode Handling and Character Encoding

Method/Feature Syntax Description Example
length Property str.length UTF-16 code units, not characters; astral symbols count as 2 'šŸ˜€'.length // 2
Code Point Escape \u{codepoint} 1-6 hex digits; supports full Unicode (0-10FFFF) '\u{1F600}' // šŸ˜€
BMP Escape \uXXXX 4 hex digits; Basic Multilingual Plane only (0-FFFF) '\u00A9' // Ā©
String.fromCharCode() String.fromCharCode(code, ...) Create from UTF-16 code units; astral chars need two codes (surrogate pair) String.fromCharCode(65) // "A"
String.fromCodePoint() String.fromCodePoint(point, ...) Create from Unicode code points; handles astral chars correctly String.fromCodePoint(0x1F600) // "šŸ˜€"
codePointAt() str.codePointAt(index) Get full Unicode code point at position 'šŸ˜€'.codePointAt(0) // 128512
charCodeAt() str.charCodeAt(index) Get UTF-16 code unit; only half of astral char (high surrogate) 'šŸ˜€'.charCodeAt(0) // 55357
normalize() str.normalize(form) Unicode normalization: NFC, NFD, NFKC, NFKD; for comparison 'cafƩ'.normalize('NFC')
localeCompare() str.localeCompare(str2, locale) Locale-aware string comparison; handles accents, case correctly 'Ƥ'.localeCompare('z', 'de')
Spread/Array.from [...str] Iterate by code points, not code units; handles emoji correctly [...'šŸ˜€šŸŽ‰'].length // 2
for...of Loop for (const char of str) Iterates by Unicode code points; emoji-safe for (const c of 'šŸ˜€')

Example: Unicode handling

// BMP characters (single code unit)
const ascii = 'A';
ascii.length; // 1
ascii.charCodeAt(0); // 65
ascii.codePointAt(0); // 65

const copyright = '\u00A9'; // Ā©
copyright.length; // 1

// Astral plane (emoji, historic scripts)
const emoji = 'šŸ˜€';
emoji.length; // 2 āŒ (surrogate pair!)
emoji.charCodeAt(0); // 55357 (high surrogate)
emoji.charCodeAt(1); // 56832 (low surrogate)
emoji.codePointAt(0); // 128512 āœ“ (full code point)

// Creating from code points
String.fromCharCode(65); // "A"
String.fromCharCode(0x00A9); // "Ā©"

// Emoji requires fromCodePoint
String.fromCodePoint(0x1F600); // "šŸ˜€"
String.fromCharCode(0x1F600); // āŒ Wrong!

// Surrogate pair manually (don't do this!)
String.fromCharCode(0xD83D, 0xDE00); // "šŸ˜€" (works but use fromCodePoint)

// Code point escape syntax
'\u{1F600}'; // "šŸ˜€"
'\u{1F4A9}'; // "šŸ’©"
'\u{1F680}'; // "šŸš€"

// Length issues with emoji
'hello'.length; // 5 āœ“
'šŸ˜€'.length; // 2 āŒ
'šŸ‘Øā€šŸ‘©ā€šŸ‘§ā€šŸ‘¦'.length; // 11 āŒ (family emoji with ZWJ)

// Count actual characters
[...'hello'].length; // 5
[...'šŸ˜€'].length; // 1 āœ“
[...'šŸ˜€šŸŽ‰'].length; // 2 āœ“

// However, combining characters still tricky
[...'šŸ‘Øā€šŸ‘©ā€šŸ‘§ā€šŸ‘¦'].length; // 7 (4 people + 3 ZWJ)

// Iterate correctly
for (const char of 'šŸ˜€šŸŽ‰') {
    console.log(char); // "šŸ˜€", "šŸŽ‰" (correct!)
}

// Split fails with emoji
'šŸ˜€šŸŽ‰'.split(''); // ['ļæ½','ļæ½','ļæ½','ļæ½'] āŒ
[...'šŸ˜€šŸŽ‰']; // ['šŸ˜€','šŸŽ‰'] āœ“

// Unicode normalization
const e1 = '\u00E9'; // Ć© (single code point)
const e2 = '\u0065\u0301'; // Ć© (e + combining acute accent)

e1 === e2; // false āŒ
e1.length; // 1
e2.length; // 2

e1.normalize() === e2.normalize(); // true āœ“

// Forms: NFC (composed), NFD (decomposed)
'cafƩ'.normalize('NFC').length; // 4
'cafƩ'.normalize('NFD').length; // 5 (e + combining accent)

// Locale-aware comparison
const strings = ['Ƥ', 'z', 'a'];
strings.sort(); // ['a', 'z', 'Ƥ'] āŒ
strings.sort((a, b) => a.localeCompare(b, 'de'));
// ['a', 'Ƥ', 'z'] āœ“ (German collation)

'Ƥ'.localeCompare('z', 'de'); // -1 (Ƥ comes before z)
'Ƥ'.localeCompare('z', 'sv'); // 1 (Ƥ comes after z in Swedish)

// Case comparison with locale
'i'.toLocaleUpperCase('en'); // "I"
'i'.toLocaleUpperCase('tr'); // "İ" (dotted capital I in Turkish)

// Real character count (approximate)
function graphemeLength(str) {
    return [...new Intl.Segmenter().segment(str)].length;
}

graphemeLength('šŸ˜€'); // 1
graphemeLength('šŸ‘Øā€šŸ‘©ā€šŸ‘§ā€šŸ‘¦'); // 1 (treats family as one grapheme)
Warning: length counts UTF-16 code units, not characters. Use [...str].length for code point count. For grapheme clusters (with ZWJ, combining marks), use Intl.Segmenter.

6. String Regular Expression Integration

Method Syntax Description Returns
match() str.match(regexp) Find matches; with /g returns all matches, without returns match details Array | null
matchAll() ES2020 str.matchAll(regexp) Iterator of all matches with capture groups; regexp must have /g flag Iterator
search() str.search(regexp) Find index of first match; ignores /g flag Index | -1
replace() str.replace(regexp|str, newStr|fn) Replace matches; without /g replaces first only String
replaceAll() ES2021 str.replaceAll(str|regexp, newStr|fn) Replace all occurrences; regexp must have /g or use string String
split() str.split(separator, limit) Split by string or regexp; optional limit on array size Array
startsWith() str.startsWith(search, pos) Check if starts with string; optional position; no regexp Boolean
endsWith() str.endsWith(search, length) Check if ends with string; optional length limit; no regexp Boolean
includes() str.includes(search, pos) Check if contains string; optional start position; no regexp Boolean
indexOf() str.indexOf(search, pos) Find first occurrence; case-sensitive; no regexp Index | -1
lastIndexOf() str.lastIndexOf(search, pos) Find last occurrence; searches backwards; no regexp Index | -1

Example: String RegExp integration

const str = 'The quick brown fox jumps over the lazy dog';

// match - without /g (first match with details)
str.match(/quick/);
// ["quick", index: 4, input: "...", groups: undefined]

str.match(/(\w+) (\w+)/);
// ["The quick", "The", "quick", index: 0, ...]

// match - with /g (all matches, no details)
str.match(/\w+/g);
// ["The", "quick", "brown", "fox", ...]

str.match(/o/g); // ["o", "o", "o", "o"]

// matchAll - all matches with details
const regex = /t(\w+)/gi;
const matches = [...str.matchAll(regex)];
matches[0]; // ["The", "he", index: 0, ...]
matches[1]; // ["the", "he", index: 31, ...]

// matchAll with named groups
const pattern = /(?<word>\w+) (?<num>\d+)/g;
const text = 'item 1, thing 2';
for (const match of text.matchAll(pattern)) {
    console.log(match.groups.word, match.groups.num);
    // "item" "1", "thing" "2"
}

// search - find position
str.search(/brown/); // 10
str.search(/cat/); // -1
str.search(/THE/i); // 0 (case-insensitive)

// replace - string or regexp
str.replace('dog', 'cat');
// "The quick brown fox jumps over the lazy cat"

str.replace(/the/gi, 'a');
// "a quick brown fox jumps over a lazy dog"

// replace with function
str.replace(/\b\w{4}\b/g, match => match.toUpperCase());
// "The QUICK brown fox JUMPS OVER the LAZY dog"

// replace with capture groups
'John Smith'.replace(/(\w+) (\w+)/, '$2, $1');
// "Smith, John"

// replace with named groups
'2025-12-17'.replace(
    /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/,
    '
const str = 'The quick brown fox jumps over the lazy dog';

// match - without /g (first match with details)
str.match(/quick/);
// ["quick", index: 4, input: "...", groups: undefined]

str.match(/(\w+) (\w+)/);
// ["The quick", "The", "quick", index: 0, ...]

// match - with /g (all matches, no details)
str.match(/\w+/g);
// ["The", "quick", "brown", "fox", ...]

str.match(/o/g); // ["o", "o", "o", "o"]

// matchAll - all matches with details
const regex = /t(\w+)/gi;
const matches = [...str.matchAll(regex)];
matches[0]; // ["The", "he", index: 0, ...]
matches[1]; // ["the", "he", index: 31, ...]

// matchAll with named groups
const pattern = /(?<word>\w+) (?<num>\d+)/g;
const text = 'item 1, thing 2';
for (const match of text.matchAll(pattern)) {
    console.log(match.groups.word, match.groups.num);
    // "item" "1", "thing" "2"
}

// search - find position
str.search(/brown/); // 10
str.search(/cat/); // -1
str.search(/THE/i); // 0 (case-insensitive)

// replace - string or regexp
str.replace('dog', 'cat');
// "The quick brown fox jumps over the lazy cat"

str.replace(/the/gi, 'a');
// "a quick brown fox jumps over a lazy dog"

// replace with function
str.replace(/\b\w{4}\b/g, match => match.toUpperCase());
// "The QUICK brown fox JUMPS OVER the LAZY dog"

// replace with capture groups
'John Smith'.replace(/(\w+) (\w+)/, '$2, $1');
// "Smith, John"

// replace with named groups
'2025-12-17'.replace(
    /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/,
    '$<month>/$<day>/$<year>'
); // "12/17/2025"

// replaceAll - all occurrences
'aaa'.replace('a', 'b'); // "baa"
'aaa'.replaceAll('a', 'b'); // "bbb"

'a-b-c'.replaceAll('-', '_'); // "a_b_c"

// split by regexp
'a1b2c3'.split(/\d/); // ["a", "b", "c", ""]
'one,two;three:four'.split(/[,;:]/);
// ["one", "two", "three", "four"]

// split with limit
'a-b-c-d'.split('-', 2); // ["a", "b"]

// includes, startsWith, endsWith (no regexp!)
str.includes('fox'); // true
str.includes('cat'); // false

str.startsWith('The'); // true
str.startsWith('the'); // false (case-sensitive)

str.endsWith('dog'); // true
str.endsWith('cat'); // false

// indexOf, lastIndexOf
str.indexOf('o'); // 12 (first 'o')
str.lastIndexOf('o'); // 41 (last 'o')

str.indexOf('the'); // -1 (case-sensitive)
str.toLowerCase().indexOf('the'); // 0

// Check from position
str.startsWith('quick', 4); // true (at index 4)
str.includes('fox', 20); // false (search starts at 20)

// Case-insensitive search
const lower = str.toLowerCase();
lower.includes('THE'.toLowerCase()); // true

// Or use regexp with /i
/THE/i.test(str); // true
#x3C;month>/
const str = 'The quick brown fox jumps over the lazy dog';

// match - without /g (first match with details)
str.match(/quick/);
// ["quick", index: 4, input: "...", groups: undefined]

str.match(/(\w+) (\w+)/);
// ["The quick", "The", "quick", index: 0, ...]

// match - with /g (all matches, no details)
str.match(/\w+/g);
// ["The", "quick", "brown", "fox", ...]

str.match(/o/g); // ["o", "o", "o", "o"]

// matchAll - all matches with details
const regex = /t(\w+)/gi;
const matches = [...str.matchAll(regex)];
matches[0]; // ["The", "he", index: 0, ...]
matches[1]; // ["the", "he", index: 31, ...]

// matchAll with named groups
const pattern = /(?<word>\w+) (?<num>\d+)/g;
const text = 'item 1, thing 2';
for (const match of text.matchAll(pattern)) {
    console.log(match.groups.word, match.groups.num);
    // "item" "1", "thing" "2"
}

// search - find position
str.search(/brown/); // 10
str.search(/cat/); // -1
str.search(/THE/i); // 0 (case-insensitive)

// replace - string or regexp
str.replace('dog', 'cat');
// "The quick brown fox jumps over the lazy cat"

str.replace(/the/gi, 'a');
// "a quick brown fox jumps over a lazy dog"

// replace with function
str.replace(/\b\w{4}\b/g, match => match.toUpperCase());
// "The QUICK brown fox JUMPS OVER the LAZY dog"

// replace with capture groups
'John Smith'.replace(/(\w+) (\w+)/, '$2, $1');
// "Smith, John"

// replace with named groups
'2025-12-17'.replace(
    /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/,
    '$<month>/$<day>/$<year>'
); // "12/17/2025"

// replaceAll - all occurrences
'aaa'.replace('a', 'b'); // "baa"
'aaa'.replaceAll('a', 'b'); // "bbb"

'a-b-c'.replaceAll('-', '_'); // "a_b_c"

// split by regexp
'a1b2c3'.split(/\d/); // ["a", "b", "c", ""]
'one,two;three:four'.split(/[,;:]/);
// ["one", "two", "three", "four"]

// split with limit
'a-b-c-d'.split('-', 2); // ["a", "b"]

// includes, startsWith, endsWith (no regexp!)
str.includes('fox'); // true
str.includes('cat'); // false

str.startsWith('The'); // true
str.startsWith('the'); // false (case-sensitive)

str.endsWith('dog'); // true
str.endsWith('cat'); // false

// indexOf, lastIndexOf
str.indexOf('o'); // 12 (first 'o')
str.lastIndexOf('o'); // 41 (last 'o')

str.indexOf('the'); // -1 (case-sensitive)
str.toLowerCase().indexOf('the'); // 0

// Check from position
str.startsWith('quick', 4); // true (at index 4)
str.includes('fox', 20); // false (search starts at 20)

// Case-insensitive search
const lower = str.toLowerCase();
lower.includes('THE'.toLowerCase()); // true

// Or use regexp with /i
/THE/i.test(str); // true
#x3C;day>/
const str = 'The quick brown fox jumps over the lazy dog';

// match - without /g (first match with details)
str.match(/quick/);
// ["quick", index: 4, input: "...", groups: undefined]

str.match(/(\w+) (\w+)/);
// ["The quick", "The", "quick", index: 0, ...]

// match - with /g (all matches, no details)
str.match(/\w+/g);
// ["The", "quick", "brown", "fox", ...]

str.match(/o/g); // ["o", "o", "o", "o"]

// matchAll - all matches with details
const regex = /t(\w+)/gi;
const matches = [...str.matchAll(regex)];
matches[0]; // ["The", "he", index: 0, ...]
matches[1]; // ["the", "he", index: 31, ...]

// matchAll with named groups
const pattern = /(?<word>\w+) (?<num>\d+)/g;
const text = 'item 1, thing 2';
for (const match of text.matchAll(pattern)) {
    console.log(match.groups.word, match.groups.num);
    // "item" "1", "thing" "2"
}

// search - find position
str.search(/brown/); // 10
str.search(/cat/); // -1
str.search(/THE/i); // 0 (case-insensitive)

// replace - string or regexp
str.replace('dog', 'cat');
// "The quick brown fox jumps over the lazy cat"

str.replace(/the/gi, 'a');
// "a quick brown fox jumps over a lazy dog"

// replace with function
str.replace(/\b\w{4}\b/g, match => match.toUpperCase());
// "The QUICK brown fox JUMPS OVER the LAZY dog"

// replace with capture groups
'John Smith'.replace(/(\w+) (\w+)/, '$2, $1');
// "Smith, John"

// replace with named groups
'2025-12-17'.replace(
    /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/,
    '$<month>/$<day>/$<year>'
); // "12/17/2025"

// replaceAll - all occurrences
'aaa'.replace('a', 'b'); // "baa"
'aaa'.replaceAll('a', 'b'); // "bbb"

'a-b-c'.replaceAll('-', '_'); // "a_b_c"

// split by regexp
'a1b2c3'.split(/\d/); // ["a", "b", "c", ""]
'one,two;three:four'.split(/[,;:]/);
// ["one", "two", "three", "four"]

// split with limit
'a-b-c-d'.split('-', 2); // ["a", "b"]

// includes, startsWith, endsWith (no regexp!)
str.includes('fox'); // true
str.includes('cat'); // false

str.startsWith('The'); // true
str.startsWith('the'); // false (case-sensitive)

str.endsWith('dog'); // true
str.endsWith('cat'); // false

// indexOf, lastIndexOf
str.indexOf('o'); // 12 (first 'o')
str.lastIndexOf('o'); // 41 (last 'o')

str.indexOf('the'); // -1 (case-sensitive)
str.toLowerCase().indexOf('the'); // 0

// Check from position
str.startsWith('quick', 4); // true (at index 4)
str.includes('fox', 20); // false (search starts at 20)

// Case-insensitive search
const lower = str.toLowerCase();
lower.includes('THE'.toLowerCase()); // true

// Or use regexp with /i
/THE/i.test(str); // true
#x3C;year>'
); // "12/17/2025" // replaceAll - all occurrences 'aaa'.replace('a', 'b'); // "baa" 'aaa'.replaceAll('a', 'b'); // "bbb" 'a-b-c'.replaceAll('-', '_'); // "a_b_c" // split by regexp 'a1b2c3'.split(/\d/); // ["a", "b", "c", ""] 'one,two;three:four'.split(/[,;:]/); // ["one", "two", "three", "four"] // split with limit 'a-b-c-d'.split('-', 2); // ["a", "b"] // includes, startsWith, endsWith (no regexp!) str.includes('fox'); // true str.includes('cat'); // false str.startsWith('The'); // true str.startsWith('the'); // false (case-sensitive) str.endsWith('dog'); // true str.endsWith('cat'); // false // indexOf, lastIndexOf str.indexOf('o'); // 12 (first 'o') str.lastIndexOf('o'); // 41 (last 'o') str.indexOf('the'); // -1 (case-sensitive) str.toLowerCase().indexOf('the'); // 0 // Check from position str.startsWith('quick', 4); // true (at index 4) str.includes('fox', 20); // false (search starts at 20) // Case-insensitive search const lower = str.toLowerCase(); lower.includes('THE'.toLowerCase()); // true // Or use regexp with /i /THE/i.test(str); // true
Note: Use match() for simple searches; matchAll() for all matches with details; replace() with functions for complex transformations. includes/startsWith/endsWith don't support regexp.

Section 10 Summary

  • Creation: Use single/double quotes for simple strings; template literals `...` for interpolation/multiline; escape sequences \n \t; Unicode \u{...} for full range
  • Methods: slice() for substrings (supports negative indices); trim/padStart/padEnd for formatting; toUpperCase/toLowerCase for case; all return new strings (immutable)
  • Template literals: `${expr}` interpolation; multiline preserves formatting; tagged templates tag`...` for custom processing (HTML escape, i18n, SQL)
  • Interpolation: Any expression; use ternary ? : not && for conditionals; ?? for null/undefined fallback; beware || with 0/false
  • Unicode: length counts UTF-16 units not characters; [...str] for code points; codePointAt/fromCodePoint for emoji; normalize() for comparison
  • RegExp: match/matchAll find patterns; replace/replaceAll modify; split divides; includes/startsWith/endsWith check (no regexp); search finds index