ESC

Type to search the knowledge base.

String Methods Worth Knowing

Practical string APIs for UI work: slice vs substring, includes/startsWith, replaceAll, trim, pad, split, and unicode awareness.

beginner3 min read
  • 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 guides