Episode 1 — Fundamentals / 1.21 — Arrays

1.21 -- JavaScript Arrays: Quick Revision

Compact cheat sheet. Print-friendly.

How to use this material (instructions)

  1. Skim before labs or interviews.
  2. Drill gaps -- reopen README.md -> 1.21.a...1.21.g.
  3. Practice -- 1.21-Exercise-Questions.md.
  4. Polish answers -- 1.21-Interview-Questions.md.

Core vocabulary

TermOne-liner
ArrayOrdered, zero-indexed, dynamic-length collection of values
IndexNumeric position starting at 0
LengthOne more than the highest index (writable property)
Sparse arrayArray with holes (missing indices) -- avoid
MutatingMethod that changes the original array in place
Non-mutatingMethod that returns a new array; original unchanged

Creating arrays

SyntaxResultNotes
[1, 2, 3][1, 2, 3]Preferred -- literal
new Array(3)[ , , ]3 empty slots -- avoid
Array.of(3)[3]Fixes single-number quirk
Array.from("abc")["a","b","c"]From iterable
Array.from({length:3}, (_,i) => i)[0, 1, 2]Generate sequence
new Array(5).fill(0)[0,0,0,0,0]Primitives only!

Type checks

typeof []              // "object" (not "array"!)
Array.isArray([])      // true -- always use this
[] instanceof Array    // true (fails across realms)

Accessing elements

OperationSyntax
Firstarr[0]
Lastarr[arr.length - 1] or arr.at(-1)
Nth from endarr.at(-n)
Out-of-boundsReturns undefined (no error)
Destructureconst [a, b, ...rest] = arr
Swap[arr[i], arr[j]] = [arr[j], arr[i]]

Adding & removing

MethodPositionMutates?Returns
push(x)EndYesNew length
pop()EndYesRemoved element
unshift(x)StartYesNew length
shift()StartYesRemoved element
push/pop   = O(1) -- fast (end)
unshift/shift = O(n) -- slow (start, re-indexes all)

Merging & copying

// concat (non-mutating)
const merged = a.concat(b);

// spread (non-mutating, more flexible)
const merged2 = [...a, ...b];
const copy = [...arr];

// with items between
const combined = [...a, 99, ...b];

In-place transformations

MethodWhat it doesMutates?
reverse()Reverses orderYes
fill(val, start, end)Fills with static valueYes
copyWithin(target, start, end)Copies section internallyYes
sort(fn)Sorts in placeYes
splice(i, del, ...items)Remove/insert at indexYes

Non-mutating copies:

[...arr].reverse()    // reversed copy
arr.toReversed()      // ES2023
arr.toSorted(fn)      // ES2023
arr.toSpliced(...)    // ES2023
arr.with(i, val)      // ES2023

Length property

arr.length              // count (highest index + 1)
arr.length = 2          // truncate (destructive!)
arr.length = 0          // clear array
arr.length = 10         // expand (creates holes)

// Empty check
arr.length === 0        // correct
if (arr) { ... }        // WRONG -- [] is truthy!

Search methods

MethodReturnsHandles NaN?
indexOf(val)Index or -1No
includes(val)BooleanYes
find(fn)Element or undefined--
findIndex(fn)Index or -1--

Iteration cheat sheet

// Classic for -- full control, break/continue
for (let i = 0; i < arr.length; i++) { arr[i] }

// for...of -- clean values, break/continue
for (const val of arr) { val }

// for...of with index
for (const [i, val] of arr.entries()) { i, val }

// AVOID for...in on arrays (string keys, prototype, unordered)

// while -- conditional / unknown count
while (arr.length > 0) { arr.shift() }

// Backwards
for (let i = arr.length - 1; i >= 0; i--) { arr[i] }
Featureforfor...offorEachwhile
breakYesYesNoYes
continueYesYesreturnYes
IndexYes.entries()2nd argYes

Reference behavior

const a = [1, 2]; const b = a;
b.push(3);
a; // [1, 2, 3] -- same reference!

// Copy (shallow)
const copy = [...a];      // or Array.from(a) or a.slice()

// Equality
[1,2] === [1,2]  // false (different references)
a === b           // true (same reference)

2D arrays (matrices)

// Create correctly
const matrix = Array.from({length: 3}, () => new Array(3).fill(0));

// NEVER: new Array(3).fill([]) -- shared reference!

// Access
matrix[row][col]

// Dimensions
matrix.length           // rows
matrix[0].length        // cols

// Iterate
for (let r = 0; r < matrix.length; r++) {
  for (let c = 0; c < matrix[r].length; c++) {
    matrix[r][c]
  }
}

Data structure patterns

Stack (LIFO):  push + pop      -- browser history, undo
Queue (FIFO):  push + shift    -- task queue, print queue

Common gotchas

GotchaFix
typeof [] === "object"Use Array.isArray()
new Array(3) creates holesUse [3] or Array.of(3)
const arr is not immutableconst locks binding, not contents
[] === [] is falseCompare element-by-element
for...in on arraysUse for or for...of
fill([]) shares referenceUse Array.from(() => [])
push returns length, not arrayStore length or ignore return
if ([]) is truthyCheck arr.length === 0

Master workflow

  1. Create -- [] literal, Array.of(), Array.from().
  2. Access -- arr[i], arr.at(-1), destructure.
  3. Modify -- push/pop (end), unshift/shift (start), splice (anywhere).
  4. Merge -- [...a, ...b] or concat.
  5. Search -- includes (boolean), find (element), indexOf (index).
  6. Iterate -- for...of (values), for (index), avoid for...in.
  7. 2D -- Array.from with factory, matrix[r][c], nested loops.

End of 1.21 quick revision.