Just JavaScript· 03
Chapter 03 · Foundations

Values and
Variables

reaction[0] = 'l' never prints "likes" — primitive values are immutable. Yet pet = 'The Kraken' clearly changes pet. No contradiction: values can't change, but variables can be re-pointed. Variables are wires.

Lab · re-point the wire

A variable is one wire you keep re-aiming

Click any value to assign it to pet. The wire swings to whatever you pick — that's all assignment does. The values themselves never move or change; only the wire's aim does.

console.log(pet)"Narwhal"

History — each line re-aims the same wire:

01

Primitive values are immutable

"Immutable" is a fancy Latin way to say unchangeable. Read-only. You can't mess with a primitive value at all.

Strings and arrays look alike — both are sequences you can index with [0]. So it's tempting to assume you can change a string's first character the way you'd change an array's first item. You can't. A string is a primitive, and every primitive is read-only. Try both below.

String · primitive
let str = 'hello';
str[0] = 'j';
console.log(str);
✗ Refused. str is still "hello". In strict mode this throws; otherwise it's silently ignored. You cannot set a property on a primitive.
Array · object
let arr = [212, 8, 506];
arr[0] = 420;
console.log(arr);
✓ Works: [420, 8, 506]. Arrays are objects, not primitives — so they're mutable.
A contradiction?

If strings can't change, why does pet = 'Narwhal'; pet = 'The Kraken' clearly change pet? Don't ignore the contradiction — chase it. It reveals a gap: we said the values can't change. We said nothing about variables.

02

Variables are wires

A variable is not a value. It's a wire: it starts at a name in your code and ends pointing at some value out in the universe.

Once you've made the pet wire, there are exactly two things you can do with it.

Assign — re-aim the wire

pet = 'The Kraken' tells JavaScript to point the wire on the left at the value on the right. Two rules:

  • The left side must be a wire. 'war' = 'peace' fails — 'war' isn't a wire. (There's another kind of wire coming in Chapter 07 — it uses a dot or square brackets.)
  • The right side must be an expression — a question that resolves to a value. count + ' Dalmatians' is fine; so are plain literals like 2 or 'The Kraken'.

Read — follow the wire

When you write pet, you're asking "what's at the end of pet's wire right now?" A variable name is itself an expression. So the same name can give different values at different times — because you've been re-aiming the wire.

Nouns and verbs

You can't skate a bike or sing a mosquito — and you can't pass a variable. You pass a value. It sounds pedantic until it bites you:

Think first
function double(x) {
  x = x * 2;
}
let money = 10;
double(money);
console.log(money); // ?
Answer · 10. What a scam.

double(money) means "figure out the value of money (which is 10) and pass that to double." Inside, x = x * 2 only re-aims the local x wire at 20. It never touches the money wire. So money is still 10.

We're keeping wires — no boxes, ever. Why not just "put" the value into the variable? Because wires are what make equality, object identity, and mutation explainable. The universe is full of wires.

03

Recap

  • Primitive values are immutable. You can't set a property on a string or number. Arrays are objects, so they're mutable.
  • Variables are not values. Each variable is a wire pointing at one value; = re-aims it.
  • Assignment: left side must be a wire, right side must be an expression. Reading a variable follows its wire to the current value.
  • You pass values, not variables — which is why double(money) leaves money untouched.