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

Part 11 — 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 questions (Part 11):

  1. Which array methods mutate vs return new? Name the immutable ES2023 additions.
  2. Why does [10,9,100].sort() give [10,100,9]? Fix it.
  3. Implement map, filter, reduce yourself.
  4. Difference between slice and splice; find vs filter; some vs every.