π§΅ String Basics β JavaScript
Parent: Strings JS Index
1. Creating Strings
const s1 = 'hello'; // single quotes
const s2 = "hello"; // double quotes
const s3 = `hello`; // template literal
const name = 'World';
const s4 = `Hello, ${name}!`; // "Hello, World!" β interpolation
// Multi-line
const multi = `Line 1
Line 2`;
2. String Length
const s = "hello";
console.log(s.length); // 5
// β οΈ Emoji and Unicode surrogates
const emoji = "π";
console.log(emoji.length); // 2 (UTF-16 code units)
console.log([...emoji].length); // 1 (actual characters via spread)
console.log(Array.from(emoji).length); // 1
3. Accessing Characters
const s = "hello";
s[0]; // 'h'
s[1]; // 'e'
s.charAt(0); // 'h'
s.at(-1); // 'o' (ES2022 β negative index!)
s.at(-2); // 'l'
// Iterate
for (const c of s) console.log(c); // h e l l o
for (let i = 0; i < s.length; i++) console.log(s[i]);
// To array
const chars = s.split(''); // ['h','e','l','l','o']
const chars2 = Array.from(s); // ['h','e','l','l','o']
const chars3 = [...s]; // ['h','e','l','l','o']
4. Substrings
const s = "Hello World";
s.slice(0, 5); // "Hello" β end exclusive
s.slice(6); // "World" β to end
s.slice(-5); // "World" β last 5
s.slice(6, 9); // "Wor"
s.substring(6, 11); // "World" β no negative support
s.substr(6, 5); // "World" β deprecated (avoid)
Prefer
sliceoversubstringand never usesubstr(deprecated).
5. Character Codes (ASCII)
'A'.charCodeAt(0); // 65
'a'.charCodeAt(0); // 97
'0'.charCodeAt(0); // 48
String.fromCharCode(65); // 'A'
String.fromCharCode(97); // 'a'
// Convert lowercase to uppercase
const c = 'e';
String.fromCharCode(c.charCodeAt(0) - 32); // 'E'
// Frequency array (a-z)
const s = "hello";
const freq = new Array(26).fill(0);
for (const c of s) freq[c.charCodeAt(0) - 97]++;
console.log(freq); // index 4=2(l), 7=1(h), 11=1(e), 14=1(o)
6. String Comparison
"apple" === "apple"; // true
"apple" < "banana"; // true (lexicographic)
"apple" === "Apple"; // false
// Case-insensitive
"Apple".toLowerCase() === "apple".toLowerCase(); // true
// For sorting
["banana","apple","cherry"].sort(); // ["apple","banana","cherry"]
["b","a","c"].sort((x,y) => x.localeCompare(y));
7. Common Operations
const s = " Hello World ";
// Trim
s.trim(); // "Hello World"
s.trimStart(); // "Hello World "
s.trimEnd(); // " Hello World"
// Case
s.toLowerCase(); // " hello world "
s.toUpperCase(); // " HELLO WORLD "
// Reverse
"hello".split('').reverse().join(''); // "olleh"
// Repeat
"ab".repeat(3); // "ababab"
// Pad
"5".padStart(3, "0"); // "005"
"5".padEnd(3, "0"); // "500"
// Replace
"hello world".replace("world","JS"); // "hello JS" (first only)
"aabbcc".replaceAll("b","X"); // "aaXXcc"
"hello".replace(/l/g, 'L'); // "heLLo" (regex global)
8. Searching in Strings
const s = "Hello World";
s.indexOf("World"); // 6
s.indexOf("world"); // -1 (case-sensitive)
s.lastIndexOf("l"); // 9
s.includes("World"); // true
s.startsWith("Hello"); // true
s.endsWith("World"); // true
// β οΈ indexOf returns -1 when not found (not false)
if (s.indexOf("Hello") !== -1) console.log("Found");
// Or more readable:
if (s.includes("Hello")) console.log("Found");
9. Split and Join
// Split into chars
"hello".split(''); // ['h','e','l','l','o']
Array.from("hello"); // ['h','e','l','l','o']
// Split by delimiter
"a,b,c".split(','); // ['a','b','c']
"a,,b".split(','); // ['a','','b']
// Split with limit
"a,b,c,d".split(',', 2); // ['a','b']
// Join
['a','b','c'].join(','); // "a,b,c"
['h','i'].join(''); // "hi"
10. Regular Expressions
const s = "JS version 20.19";
// Match first
s.match(/\d+\.\d+/); // ["20.19"]
s.match(/\d+/); // ["20"]
// Match all (requires /g flag)
[...s.matchAll(/\d+/g)].map(m => m[0]); // ["20","19"]
// Test (boolean)
/^\d+$/.test("123"); // true
/^\d+$/.test("12a"); // false
// Replace with regex
"hello world".replace(/\b\w/g, c => c.toUpperCase()); // "Hello World"
// Split by regex
"a b c".split(/\s+/); // ['a','b','c']
11. Template Literals & String Formatting
const n = 42;
`${n}`.padStart(5, '0'); // "00042"
n.toFixed(2); // "42.00"
// Formatting money
const formatMoney = (n) => `$${n.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')}`;
formatMoney(1234567.5); // "$1,234,567.50"
// Tagged templates
function highlight(strings, ...values) {
return strings.reduce((res, str, i) => res + str + (values[i] ? `[${values[i]}]` : ''), '');
}
const name = "World";
highlight`Hello ${name}!`; // "Hello [World]!"
12. Key Patterns for Interviews
Pattern 1 β Two Pointers (Palindrome)
function isPalindrome(s) {
let lo = 0, hi = s.length - 1;
while (lo < hi) {
if (s[lo] !== s[hi]) return false;
lo++; hi--;
}
return true;
}
Pattern 2 β Frequency Map (Anagram)
function isAnagram(a, b) {
if (a.length !== b.length) return false;
const freq = new Array(26).fill(0);
for (let i = 0; i < a.length; i++) {
freq[a.charCodeAt(i) - 97]++;
freq[b.charCodeAt(i) - 97]--;
}
return freq.every(v => v === 0);
}
Pattern 3 β Sliding Window (Longest No-Repeat)
function lengthOfLongestSubstring(s) {
const map = new Map();
let max = 0, left = 0;
for (let r = 0; r < s.length; r++) {
if (map.has(s[r]) && map.get(s[r]) >= left) left = map.get(s[r]) + 1;
map.set(s[r], r);
max = Math.max(max, r - left + 1);
}
return max;
}
Common Mistakes
| Mistake | Problem | Fix |
|---|---|---|
s[i] = 'x' | Strings are immutable | Convert to array, modify, rejoin |
s.length() | length is a property, not method | s.length |
s.indexOf(x) == false | indexOf returns 0 when found at start (falsy) | !== -1 |
s.substr(i, n) | Deprecated | Use s.slice(i, i+n) |
typeof s === 'string' vs s instanceof String | String object vs primitive | Use typeof for primitives |
Regex without /g for replace | Only replaces first match | Use replaceAll or /g flag |