DAY 1 / 30 · WEEK 1

JS Essentials for DSA

Goal of the day

Concept

Think of an array like a row of numbered lockers at a gym. Each locker has a fixed position (its index), so you can open any locker instantly if you know its number — that's why arr[2] is instant (O(1)).

The four basic ways to add/remove elements all come down to one question: does anything else have to move?

Destructuring is a shortcut for pulling values out of an array into named variables in one line, instead of writing arr[0], arr[1] separately — that part really is free, it's just reading. Spread (...) goes the other way — it builds a whole new array by copying every value out of the old one. That copy is still real work: O(n), same cost as writing the loop yourself. Spread doesn't add a new capability, it's just a cleaner way to write a copy loop you could've written by hand.

Diagrams

Our running example throughout this lesson is a 5-element array: arr = [4, 7, 2, 9, 5] — big enough to actually see which elements move and which don't.

push(6) / pop() — end of the array 4 7 2 9 5 6 Only the last slot moves — 4, 7, 2, 9, 5 stay put → O(1). pop() is the same in reverse: delete the last slot only. unshift(1) / shift() — front of the array 1 4 7 2 9 5 Amber boxes all shift right first, to free up index 0 → O(n). shift() reverses this: remove index 0, then shift everyone left.

Interactive visualizations

just added / added by spread shifting to make room / close a gap reading / current index untouched

1. push, pop, unshift, shift — where does the cost come from?

Press Play or Step to begin.

2. Destructuring and spread

Press Play or Step to begin.

The code

// arr is a normal JS array — a contiguous, indexed list.
const arr = [4, 7, 2, 9, 5];

// push/pop touch only the END. Nothing else has to move. O(1).
arr.push(6);   // arr is now [4, 7, 2, 9, 5, 6]
arr.pop();     // arr is back to [4, 7, 2, 9, 5]

// unshift/shift touch the START. Every other element has to
// shift over to make room (or close the gap). O(n).
arr.unshift(1); // arr is now [1, 4, 7, 2, 9, 5] — everyone else shifted right
arr.shift();    // arr is back to [4, 7, 2, 9, 5] — everyone else shifted left

// Reading by index is O(1): JS jumps straight to that memory slot.
const first = arr[0]; // 4

// Destructuring unpacks values into named variables in one line.
// It's identical to writing arr[0], arr[1], arr[2], arr[3], arr[4] separately.
const [a, b, c, d, e] = arr; // a=4, b=7, c=2, d=9, e=5

// Spread (...) copies every element of arr into a NEW array,
// then we add 6 at the end. arr itself is never changed.
const merged = [...arr, 6]; // [4, 7, 2, 9, 5, 6]

Line by line:

Dry run

StepCodearra, b, c, d, emerged
1const arr = [4,7,2,9,5][4,7,2,9,5]
2arr.push(6)[4,7,2,9,5,6]
3arr.pop()[4,7,2,9,5]
4arr.unshift(1)[1,4,7,2,9,5]
5arr.shift()[4,7,2,9,5]
6const [a,b,c,d,e] = arr[4,7,2,9,5]4, 7, 2, 9, 5
7const merged = [...arr, 6][4,7,2,9,5]4, 7, 2, 9, 5[4,7,2,9,5,6]

Complexity

OperationTimeSpaceWhy
Read by index arr[i]O(1)O(1)Contiguous memory — index math jumps straight there.
Destructure n values*O(n)O(1) extraHas to read n slots, one per variable.
Spread copy [...arr]O(n)O(n)Every element must be copied into the new array.
push / pop (end)O(1)†O(1)No shifting — just add/remove the last slot.
unshift / shift (start)O(n)O(1)Every remaining element has to shift one slot over.

*Here n is the number of variables you're destructuring, not the array's length — const [a, b] = hugeArray is O(2), not O(hugeArray.length). †Amortized — occasionally the engine has to grow the underlying array, but on average it's O(1).

Interview corner

How to talk through it out loud: say the plan before you type: "I'll destructure the first two values since I only need those, then use spread to build a new array without mutating the input — that keeps this O(n) instead of accidentally O(n²) from copying in a loop." Naming the shallow-copy gotcha unprompted is a strong signal to an interviewer that you've been burned by it before.

Practice problems

All three below are warm-ups (Easy) — Day 1 is about getting comfortable with the syntax. Real easy → medium pattern problems start from Day 3 onward, once we've built up more tools.

1. Concatenation of Array (Easy — LeetCode: Concatenation of Array)

Given an array nums, return an array ans of length 2n where ans is nums concatenated with itself.

2. Running Sum of 1d Array (Easy — LeetCode: Running Sum of 1d Array)

Given an array nums, return a new array where each element is the sum of itself and every element before it.

3. Shuffle the Array (Easy — LeetCode: Shuffle the Array)

Given nums = [x1,...,xn, y1,...,yn], return the array in the shuffled form [x1,y1,x2,y2,...,xn,yn].

Quiz

1. What does const [a, , c] = [1, 2, 3] set c to?

2. What is [...[1, 2], ...[3, 4]]?

3. Is [...arr] a shallow copy or a deep copy?

4. Which one runs in O(1) time: push or unshift?

5. What is a after const {a = 5} = {}?