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 and String Manipulation

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