String Methods Worth Knowing
Practical string APIs for UI work: slice vs substring, includes/startsWith, replaceAll, trim, pad, split, and unicode awareness.
- javascript
- string-methods
Strings show up in every UI ticket. You don’t need every esoteric method — you need the ones that replace buggy hand-rolled loops and the ones that surprise you with immutability and Unicode.
Strings are immutable: methods return new strings.
Search and test
const s = 'Frontend Beauty';
s.includes('end'); // true
s.startsWith('Front'); // true
s.endsWith('ty'); // true
s.indexOf('e'); // 2
s.lastIndexOf('e');
s.search(/beauty/i); // index or -1
Prefer includes/startsWith/endsWith over indexOf !== -1 for readability.
Slice family
'abcdef'.slice(1, 4); // 'bcd'
'abcdef'.slice(-2); // 'ef'
'abcdef'.substring(1, 4); // 'bcd' — negative treated as 0
'abcdef'.substr(1, 3); // legacy; avoid
slice is the default choice (supports negatives consistently).
Transform
' hi '.trim();
' hi '.trimStart();
'hi'.padStart(4, '0'); // '00hi'
'hi'.padEnd(4, '.');
'Hello'.toLowerCase();
'i'.toLocaleUpperCase('tr'); // Turkish I rules matter for some locales
Replace
'a-a-a'.replace('-', '_'); // 'a_a-a' — first only
'a-a-a'.replace(/-/g, '_'); // all
'a-a-a'.replaceAll('-', '_'); // all, string or global regex
replace with string pattern replaces once; with regex needs g for all. Callback form:
'price 12'.replace(/\d+/, (m) => String(Number(m) * 2));
Split / join
'a,b,c'.split(',');
'a,b,c'.split(',', 2); // ['a','b']
'hello'.split(''); // chars — careful with emoji
[...'👍'].length; // 1 with spread iterator
'👍'.length; // 2 UTF-16 code units
For user-perceived characters, use Intl.Segmenter or careful unicode iteration — not naive length.
Template adjacent
const name = 'Ada';
`Hi ${name}!`;
Tagged templates are a separate topic; plain interpolation covers most UI copy.
Practical UI snippets
function ellipsis(str, max) {
if (str.length <= max) return str;
return str.slice(0, max - 1) + '…';
}
function slugify(str) {
return str
.trim()
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '');
}
Interview answer (out loud)
“Strings are immutable; methods return new values. I use includes/startsWith, slice for substrings, replaceAll or regex with g for global replace, and trim/pad for forms. length counts UTF-16 units so emoji needs care. I avoid substr and prefer slice.”
Normalization and comparison
// Unicode normalize before compare / store
const a = 'é'.normalize('NFC');
const b = 'e\u0301'.normalize('NFC');
a === b; // true after NFC
// Case fold for search
haystack.toLocaleLowerCase('en').includes(needle.toLocaleLowerCase('en'));
User-facing search should decide locale and normalization once; naive toLowerCase is fine for ASCII product SKUs, wrong for Turkish i/İ if that’s your market.
Building vs mutating myths
let s = 'ab';
s[0] = 'X'; // ignored in strict? assignment to index is no-op / error in strict for string primitive boxing quirks
s = 'X' + s.slice(1); // real update
Treat strings as values. In hot loops, push parts into an array and join('') once rather than repeatedly concatenating huge strings (engines optimize concat, but arrays stay clearer for many pieces).
Character classes without regex
function isAsciiDigit(ch) {
return ch >= '0' && ch <= '9';
}
// Prefer regex or Intl for real number parsing
For simple scanners (CSV lite, log lines), index loops + slice beat giant regexes you can’t read six months later.
Further reading
Related
- Template Literals and Tagged Templates
- Regular Expressions Essentials
- Intl API Formatting
- Type Coercion Rules
Related guides
- AbortControllerCancel fetch and other async work with AbortController and AbortSignal — timeouts, race conditions, and cleanup when components unmount.
- Array find, some, every, includesShort-circuiting array predicates: find, findIndex, some, every, and includes — when to use each and common interview traps.
- Array map, filter, reducemap, filter, and reduce as the core transform toolkit — immutability, chaining costs, reduce patterns, and when a plain loop is clearer.
- Arrow Functions Deep DiveLexical this, no arguments object, no construct, concise bodies — when arrows help and when methods and generators need classic functions.
- Async Iteration and for await...ofAsync iterables, for await...of, and streaming data — how async iterators differ from Promise.all and when to use each.