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

Arrays

Method reference, reduce deeply, Creating & copying, Holes & sparse arrays ⚠️, Time complexity 🎯

Arrays are ordered, index-keyed objects with a magic length. They can be sparse (have holes).

Method reference#

Method Mutates? Returns Notes
push/pop new length / removed end operations, O(1)
shift/unshift removed / new length front ops, O(n)
splice(i, del, ...add) removed items insert/remove/replace
sort(cmp) same array default sorts as strings ⚠️
reverse same array
fill(v, s, e) same array
copyWithin same array rarely used
map(fn) new array transform
filter(fn) new array keep truthy
reduce(fn, init) any fold; always pass init
reduceRight any right-to-left
slice(s, e) new array copy a range (also shallow-copies)
concat(...) new array merge
flat(depth) new array flatten nested
flatMap(fn) new array map then flat 1
find/findIndex item / index first match
findLast/findLastIndex 🟢 item / index from the end
some/every boolean any / all
includes(v) boolean uses SameValueZero (finds NaN)
indexOf/lastIndexOf index uses === (won't find NaN)
join(sep) string
at(i) 🟢 item supports negatives: arr.at(-1)
keys/values/entries iterator
toSorted/toReversed/toSpliced/with 🟢 new array immutable versions (ES2023)
[3, 12, 2].sort();                 // [12, 2, 3] ⚠️ string sort!
[3, 12, 2].sort((a, b) => a - b);  // [2, 3, 12] ✅ numeric
[1, [2, [3]]].flat(Infinity);      // [1, 2, 3]
["a", "b"].at(-1);                 // "b"
const sorted = arr.toSorted((a,b)=>a-b);   // original arr untouched 🟢
arr.with(0, 99);                   // copy with index 0 replaced

reduce deeply#

// sum
[1,2,3].reduce((acc, n) => acc + n, 0);        // 6
// group
["a","b","a"].reduce((m, k) => (m[k]=(m[k]||0)+1, m), {}); // {a:2, b:1}
// pipe (function composition)
const run = (x, fns) => fns.reduce((v, f) => f(v), x);

⚠️ Always pass an initial value; without it, an empty array throws and the first element becomes the accumulator.

Creating & copying#

Array.of(7);            // [7]         (vs Array(7) → 7 empty slots)
Array.from("abc");      // ["a","b","c"]
Array.from({length:3}, (_, i) => i);  // [0,1,2]
[...new Set([1,1,2])];  // [1,2]  dedupe
await Array.fromAsync(asyncIterable);  // 🟢 ES2024

Holes & sparse arrays ⚠️#

const s = [1, , 3];       // hole at index 1
s.length;                 // 3
s.forEach(x => {});       // skips the hole
s.map(x => 0);            // [0, <hole>, 0] — preserves holes
s.indexOf(undefined);     // -1 (holes aren't `undefined`)

Time complexity 🎯#

Operation Complexity
Index access arr[i] O(1)
push/pop O(1) amortized
shift/unshift O(n) (reindex)
splice (middle) O(n)
search indexOf/includes/find O(n)
sort O(n log n)
concat/slice/spread copy O(n)

For frequent front insertion, a plain array's unshift is O(n); consider a different structure or push+reverse.

Interview Q&A#

Q1. Which array methods mutate vs return new? Name the immutable ES2023 additions. Mutating: push/pop/shift/unshift, splice, sort, reverse, fill, copyWithin. Non-mutating (return new): map, filter, slice, concat, flat/flatMap, reduce. ES2023 added immutable counterparts: toSorted, toReversed, toSpliced, and with.

Q2. Why does [10,9,100].sort() give [10,100,9]? Fix it. Default sort coerces elements to strings and compares lexicographically, so "100" < "9". Pass a numeric comparator: arr.sort((a, b) => a - b).

Q3. Implement map, filter, reduce yourself.

const map = (a, fn) => { const r = []; for (let i = 0; i < a.length; i++) r.push(fn(a[i], i, a)); return r; };
const filter = (a, fn) => { const r = []; for (let i = 0; i < a.length; i++) if (fn(a[i], i, a)) r.push(a[i]); return r; };
const reduce = (a, fn, init) => { let acc = init; for (let i = 0; i < a.length; i++) acc = fn(acc, a[i], i, a); return acc; };

Q4. slice vs splice; find vs filter; some vs every? slice(s,e) returns a shallow copy without mutating; splice(i,del,...add) mutates in place and returns removed items. find returns the first matching element (or undefined); filter returns all matches as a new array. some is true if any element passes; every is true only if all do.