Using JavaScript for Interview Prep? Use This Cheat Sheet
As I work through interview prep for full-stack software engineering roles, I’ve chosen JavaScript as my language for data structures and algorithms.
Many people choose Python for its concise syntax. On LeetCode, Python solutions often look impressively short. But JavaScript is the language I know best, and I don’t want to compound the mental load by learning Python at the same time. LeetCode is enough mental load on its own.
I did find myself constantly reaching for the MDN docs to check method signatures, though. So I put together this cheat sheet for the types, methods, and common operations I use most often. ECMAScript keeps adding useful methods, too, making JavaScript feel a little closer to Python for this kind of work.
I hope you find it helpful in your own interview prep—or just as a general JavaScript reference.
Arrays
// Adding/removing elements
arr.push(x) // add to end, O(1) amortized
arr.pop() // remove from end, O(1)
arr.unshift(x) // add to start, O(n)
arr.shift() // remove from start, O(n)
arr.splice(start, deleteCount, ...items) // remove/insert anywhere, O(n)
arr.toSpliced(start, deleteCount, ...items) // non-mutating splice
arr.with(index, value) // non-mutating arr[index] = value
arr.slice(start, end) // shallow copy of a range (end is exclusive)
arr.slice(start) // slice from start through the end
// Searching
arr.indexOf(x)
arr.lastIndexOf(x)
arr.includes(x)
arr.find(predicate)
arr.findIndex(predicate)
arr.findLast(predicate)
arr.findLastIndex(predicate)
// Iteration/transformation
arr.map(fn)
arr.filter(fn)
arr.reduce(fn, initialValue)
arr.forEach(fn)
arr.flat(depth)
arr.flatMap(fn)
// Sorting/ordering
arr.sort((a, b) => a - b) // mutates; always pass a comparator for numbers
arr.toSorted((a, b) => a - b) // non-mutating sort
arr.reverse() // mutates
arr.toReversed() // non-mutating reverse
// Other essentials
Array.from(iterableOrArrayLike, mapFn)
Array.from({ length: n }, (_, i) => i)
Array.isArray(x)
arr.join(separator)
arr.fill(value)
arr.every(fn)
arr.some(fn)
arr.at(index) // supports negative indices
new Array(n).fill(0) // initialize a fixed-size array
Strings
str.slice(start, end)
str.slice(start) // slice from start through the end
str.substring(start, end)
str.split(separator)
str.charAt(i)
str[i]
str.at(i) // supports negative indices, e.g. str.at(-1)
str.charCodeAt(i)
String.fromCharCode(code)
str.indexOf(substring)
str.includes(substring)
str.startsWith(substring)
str.endsWith(substring)
str.replace(pattern, replacement)
str.replaceAll(pattern, replacement)
str.repeat(n) // "ab".repeat(3) => "ababab"
str.padStart(length, character)
str.padEnd(length, character)
str.localeCompare(other)
// Unicode-aware code point manipulation
c.codePointAt(0)
String.fromCodePoint(code)
// Checking character types with regular expressions
const isLetter = c => /^[a-z]$/i.test(c)
const isDigit = c => /^[0-9]$/.test(c)
const isAlphaNumeric = c => /^[a-z0-9]$/i.test(c)
// Checking ASCII character types with character codes
const isLowerCase = c => {
const code = c.charCodeAt(0)
return code >= 97 && code <= 122 // "a"-"z"
}
const isUpperCase = c => {
const code = c.charCodeAt(0)
return code >= 65 && code <= 90 // "A"-"Z"
}
const isDigitCode = c => {
const code = c.charCodeAt(0)
return code >= 48 && code <= 57 // "0"-"9"
}
// Case conversion via ASCII code shift
// Only use these when you already know the input's case.
const upperToLower = c => String.fromCharCode(c.charCodeAt(0) + 32)
const lowerToUpper = c => String.fromCharCode(c.charCodeAt(0) - 32)
// Built-in case conversion is clearer for general use.
c.toLowerCase()
c.toUpperCase()
// Looping over UTF-16 code units (usually what ASCII problems need)
for (let i = 0; i < str.length; i++) {
const c = str[i]
}
// Looping over Unicode code points (handles surrogate pairs/emoji)
for (const c of str) {
// ...
}
// Convert code points to an array, then use array methods
[...str].forEach(c => {
// ...
})
// Simple for ASCII, but splits surrogate pairs
str.split("").forEach(c => {
// ...
})
// Template literals for interpolation
const result = `${a}-${b}`
Objects
Object.keys(obj)
Object.values(obj)
Object.entries(obj)
Object.assign(target, ...sources) // merge/shallow copy
Object.freeze(obj)
Object.hasOwn(obj, key) // own property only; safer than obj.hasOwnProperty(key)
key in obj // own or inherited property
Object.fromEntries(iterable) // build an object from [key, value] pairs
Object.groupBy(items, keyFn) // returns a plain object
Map.groupBy(items, keyFn) // returns a Map
// Example: group numbers by parity
Object.groupBy(nums, n => n % 2 === 0 ? "even" : "odd")
// Optional chaining and nullish coalescing for safe access
obj?.a?.b ?? defaultValue
Map and Set
// Map
map.set(key, value)
map.get(key)
map.has(key)
map.delete(key)
map.size
// Maps iterate in insertion order; lookups are O(1) on average.
for (const [key, value] of map) {
// ...
}
// Add a value only if the key does not exist.
if (!map.has(key)) map.set(key, defaultValue)
// Frequency count / "get or default" pattern
map.set(key, (map.get(key) ?? 0) + 1)
// Group values into arrays
if (!map.has(key)) map.set(key, [])
map.get(key).push(value)
// Set
set.add(x)
set.has(x)
set.delete(x)
set.size
const deduped = [...new Set(arr)]
// Modern Set operations
setA.union(setB)
setA.intersection(setB)
setA.difference(setB)
setA.symmetricDifference(setB)
setA.isSubsetOf(setB)
setA.isSupersetOf(setB)
setA.isDisjointFrom(setB)
Numbers and Math
Math.max(...args)
Math.min(...args)
Math.max(...arr) // convenient for reasonably sized arrays
Math.floor(x)
Math.ceil(x)
Math.round(x)
Math.trunc(x)
Math.abs(x)
Math.pow(x, y) // or x ** y
Math.sqrt(x)
parseInt(str, radix)
parseFloat(str)
Number.isInteger(x)
Number.isFinite(x)
Number.isNaN(x) // safer than global isNaN
Number.MAX_SAFE_INTEGER
Number.MIN_SAFE_INTEGER
n.toString(radix) // e.g. n.toString(2) for binary
JavaScript numbers use floating-point representation, so integers are only exact between Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER. Use BigInt when a problem can exceed that range, but remember that you cannot mix number and bigint values in arithmetic.
const big = 12345678901234567890n
const doubled = big * 2n
Bitwise Operators
a & b // AND
a | b // OR
a ^ b // XOR
~a // NOT (bitwise complement)
a << b // left shift
a >> b // right shift, sign-preserving
a >>> b // unsigned right shift
// Common tricks
n & 1 // 1 when odd, 0 when even
n >> 1 // signed division by two via bit shift
n << 1 // multiply by two within the 32-bit range
n & (n - 1) // clear the lowest set bit
n & -n // isolate the lowest set bit
a ^ b // useful for finding a unique element among pairs
~n // equivalent to -(n + 1)
// A positive power of two has exactly one set bit.
const isPowerOfTwo = n => n > 0 && (n & (n - 1)) === 0
Interview Tips
// Initialize a 2D grid with independent rows.
const grid = Array.from(
{ length: rows },
() => new Array(cols).fill(0)
)
// Avoid this: every row points to the same inner array.
const brokenGrid = new Array(rows).fill(new Array(cols).fill(0))
// Clone before sorting to preserve the original.
const sorted = [...arr].sort((a, b) => a - b)
// Destructuring for swaps and multi-value returns
[arr[i], arr[j]] = [arr[j], arr[i]]
const [a, b] = arr
const { x, y } = obj
// Use a head index for an O(1) queue dequeue instead of shift(), which is O(n).
const queue = []
let head = 0
queue.push(value)
const next = queue[head++]
while (head < queue.length) {
const current = queue[head++]
// ...
}