computer just lie to you?
Welcome to the world of mutable and immutable. Two words that explain a
ton of "wait, why did that change?" bugs.
The idea in one line
Mutable means "can be changed after it's made." Immutable means "locked
forever once it's made."
The metaphor: a whiteboard vs a printed photo
WHITEBOARD (mutable) PRINTED PHOTO (immutable)
wipe it, rewrite it can't edit it
same board, new content want a change? print a NEW photo
A whiteboard is mutable. You change what's on it, but it's still the same
board. A printed photo is immutable. You can't change it. If you want a
different picture, you make a brand new print and keep (or toss) the old one.
How it bites you in code
const original = [1, 2, 3]
const copy = original // NOT a copy! both names point to the SAME array
copy.push(4)
console.log(original) // [1, 2, 3, 4] <- surprise! the original changed too
copy = original did not make a new array. It just gave the same whiteboard
a second name. Writing through one name shows up under the other. Arrays and
objects in JavaScript are mutable, so this trap is everywhere.
// The fix: make a real new array (a fresh print), then change that
const original = [1, 2, 3]
const copy = [...original] // new array with the same items
copy.push(4)
console.log(original) // [1, 2, 3] <- safe!
console.log(copy) // [1, 2, 3, 4]
A real case: React state
React leans hard on immutability. If you change state in place, React often
can't tell anything changed, so your screen doesn't update.
// Wrong: mutating the same array. React may not re-render.
todos.push(newTodo)
setTodos(todos)
// Right: hand React a brand new array
setTodos([...todos, newTodo])
The rule "don't mutate state, replace it" is this exact idea. Treat state like a
printed photo: make a new one instead of scribbling on the old.
Gotchas juniors hit
1. Thinking = copies.
For arrays and objects, = copies the reference (the name), not the contents.
Both names share one thing.
2. const does not mean immutable.
const arr = [1,2] just means you can't point arr at something else. You can
still arr.push(3). The box is locked; the contents are not.
3. Shallow copies only go one level deep.
[...arr] copies the top level. Nested objects inside are still shared. Deep
data needs deeper copying.
Recap
-
Mutable = changeable after creation (a whiteboard).
-
Immutable = locked after creation (a printed photo).
- In JS,
= shares the same thing; it does not copy it.
- For safe updates (especially React state), make a new value instead of
changing the old one.
Your turn
Run the const copy = original; copy.push(4) example yourself and watch the
original change. Then fix it with [...original]. Once that "aha" lands, explain
"whiteboard vs printed photo" to a friend.