Topics in this subject
JavaScript 3 min read Updated 5 Aug 2026

Strings

Common methods, Template literals & tagged templates, Unicode reality ⚠️ 🎯, Regex quick primer

Strings are immutable UTF-16 sequences.

Common methods#

Method Purpose
length number of UTF-16 units (not always code points)
at(i) / charAt(i) char; at supports negatives
slice(s,e) / substring(s,e) extract (slice allows negatives)
toUpperCase/toLowerCase case
trim/trimStart/trimEnd whitespace
includes/startsWith/endsWith membership
indexOf/lastIndexOf position
replace(a,b) / replaceAll(a,b) replace (regex or string)
split(sep) → array
padStart/padEnd(len, pad) pad
repeat(n) repeat
concat / + join (prefer +/templates)
match/matchAll/search regex
normalize() Unicode normalization
codePointAt/fromCodePoint full Unicode
localeCompare locale-aware compare/sort

Template literals & tagged templates#

const name = "Ada";
`Hi ${name}, ${1 + 1} lights`;     // interpolation + expressions
`line1
line2`;                            // real newlines

// tagged template: a function receives the parts
function html(strings, ...values) {
  return strings.reduce((out, s, i) =>
    out + s + (values[i] != null ? escape(values[i]) : ""), "");
}
const safe = html`<p>${userInput}</p>`;  // e.g. auto-escaping

Unicode reality ⚠️ 🎯#

"😀".length;               // 2 — it's a surrogate pair, not 1
[..."😀"].length;          // 1 — spread iterates code points
"a".localeCompare("z");    // locale-aware ordering
"café".normalize("NFC");   // combine accent into one code point

Iterating a string with for...of or spread respects code points; indexing by [i] and .length count UTF-16 units.

Regex quick primer#

const re = /(\d{4})-(\d{2})-(\d{2})/;      // groups
"2025-01-31".match(re);                    // ["2025-01-31","2025","01","31",...]
"a1b2".replace(/\d/g, "#");                // "a#b#"
[..."a1b2".matchAll(/(\w)(\d)/g)];         // iterate all matches with groups
/(?<year>\d{4})/.exec("2025").groups.year; // named groups → "2025"

Flags: g global, i ignore case, m multiline, s dotall, u unicode, y sticky, d indices.

Interview Q&A#

Q1. Why is "😀".length === 2? How do you count real characters? Strings are UTF-16, and 😀 is outside the BMP so it's stored as a surrogate pair (two code units). Count code points with [..."😀"].length or Array.from("😀").length, which iterate by code point.

Q2. slice vs substring vs substr? slice(s,e) supports negative indices (counting from the end). substring(s,e) treats negatives as 0 and swaps the args if s > e. substr(start, length) takes a length, not an end index, and is deprecated — avoid it.

Q3. Difference between replace and replaceAll; replace all with replace? replace swaps only the first match for a string argument; replaceAll swaps every occurrence. To replace all with replace, use a global regex: str.replace(/x/g, "y").

Q4. What are tagged templates good for? A tag function receives the literal strings array and the interpolated ...values separately, letting you process them — e.g. auto-escaping HTML/SQL, i18n, or styled-components-style CSS-in-JS.