Explorer
JavaScript

Arrays in javascript

JavaScript Theory & Concepts

Arrays in JavaScript

Deep dive into memory layout, mutation vs immutability, and essential built-in operations.

📖 The Story & Real-World Analogy

The Swiss Army Train of Compartments

"Imagine a futuristic magnetic train made of numbered cargo cars (`[0], [1], [2]...`). Unlike old rigid steam trains where every car had to be the exact same size and carry only coal (rigid typed C arrays), this JS train can carry a passenger in car 0, a motorcycle in car 1, and a pizza in car 2! You can couple new cars to the caboose (`push`), uncouple the locomotive (`shift`), or take a clean photographic snapshot of cars 2 to 4 without cutting the train in half (`slice`)."

JavaScript arrays are special list-like objects whose prototype is `Array.prototype`. Under the hood in engines like V8, dense packed arrays are stored as contiguous memory for speed, while sparse arrays transition to dictionary mode.

⚙️ How It Works Under The Hood (Step-by-Step)
1

V8 Array Elements Kinds

V8 tracks internal element kinds: `PACKED_SMI_ELEMENTS` (small integers), `PACKED_DOUBLE_ELEMENTS` (floats), and `PACKED_ELEMENTS` (mixed objects/strings). Adding holes creates `HOLEY` variants that are slower.

2

Mutating Methods (Change in Place)

`push()`, `pop()`, `shift()`, `unshift()`, `splice()`, `reverse()`, and `sort()`. These alter the original array in memory.

3

Non-Mutating Methods (Return New Array)

`concat()`, `slice()`, `map()`, `filter()`, `flat()`, and modern ES2023 additions: `toSorted()`, `toReversed()`, and `toSpliced()`.

4

Higher-Order Iterators

`forEach()`, `map()`, `filter()`, `reduce()`, `some()`, `every()`, `find()`, and `findIndex()`. These accept callbacks and improve readability over imperative for-loops.

💻 Interactive Code Walkthrough

Comparing in-place mutation vs modern non-mutating transformations:

JAVASCRIPT
const scores = [45, 92, 18, 77];

// Mutating sort (converts elements to strings by default if comparator omitted!)
const mutated = [...scores].sort((a, b) => a - b);
console.log("Sorted:", mutated);

// Non-mutating pipeline
const passingBonus = scores
  .filter(score => score >= 50)
  .map(score => score + 5);

console.log("Passing with bonus:", passingBonus);
console.log("Original scores untouched:", scores);
Console Output:
CODE
Sorted: [ 18, 45, 77, 92 ]
Passing with bonus: [ 97, 82 ]
Original scores untouched: [ 45, 92, 18, 77 ]
⚠️ Common Pitfalls & Interview Traps
Trap
Default sort() Lexicographical Trap

The Risk: `[10, 2, 25, 5].sort()` produces `[10, 2, 25, 5]` because it stringifies elements before comparing (`"10"` comes before `"2"`).

The Fix: Always supply an explicit numeric comparator: `arr.sort((a, b) => a - b)` for ascending order.

Trap
Confusing splice() with slice()

The Risk: `arr.splice(start, count)` modifies the array in-place, whereas `arr.slice(start, end)` returns a shallow copy without touching original.

The Fix: Remember: **sp**lice **sp**lits the original array; **sl**ice takes a **sl**ice copy.

⚡ 30-Second Quick Revision Cheat Sheet (TL;DR)
  • ✓ Arrays are reference types stored in the Heap.
  • ✓ Use `slice()`, `concat()`, or spread `[...arr]` for immutability in React/Redux.
  • ✓ Always pass a comparator to `.sort((a, b) => a - b)`.
  • ✓ Use `find()` / `findIndex()` to locate single items; `filter()` for all matches.
  • ✓ Avoid creating sparse arrays with holes (e.g. `arr[1000] = "x"`) to keep V8 optimizations.

Finished this lesson?

Mark this chapter complete to update your learning streak and unlock the next lesson.