Copying Objects (and the Reference Trap)

Grade 8, page 10 of 13. A two-minute read.

In Grade 7, you saw that assigning an array to a new variable doesn't copy it. Objects work exactly the same way. Let's draw a picture this time:

Two variables, one object. Changes made through either name affect the same object.
JavaScript
const a = { score: 10 };
const b = a;

b.score = 99;

console.log(a.score);

It prints

99

The variables a and b aren't two boxes each holding an object. They're two arrows pointing at the same object in memory. Programmers say that objects (and arrays) are stored by reference. Change the object through b, and when you look at it through a, you see the change, because there's only one object.

(Primitive values like numbers and strings are different. They're copied when you assign them. let x = 5; let y = x; y = 10; leaves x as 5.)

Making a real copy

To make a separate copy, use the spread syntax with curly braces:

JavaScript
const original = { score: 10, level: 1 };
const copy = { ...original };

copy.score = 99;

console.log(original);
console.log(copy);

It prints

{ score: 10, level: 1 }
{ score: 99, level: 1 }

Spread is also fantastic for merging objects. Later properties overwrite earlier ones with the same key:

JavaScript
const defaults = { theme: "light", fontSize: 16, sound: true };
const userSettings = { theme: "dark", fontSize: 20 };

const settings = { ...defaults, ...userSettings };
console.log(settings);

It prints

{ theme: 'dark', fontSize: 20, sound: true }

The user's choices win, and anything they didn't choose falls back to the default. This exact pattern is used in countless apps.

Professor’s CornerShallow copies

Spread makes a shallow copy: it copies the top-level properties, but if one of those properties is itself an object or array, the inner object is still shared between the original and the copy. For a complete, deep copy of everything, modern JavaScript has a built-in function called structuredClone(obj). For simple, flat objects, spread is all you need.

Comparing objects

Because objects are compared by reference, two objects that look identical are not equal unless they're literally the same object:

JavaScript
const x = { a: 1 };
const y = { a: 1 };
const z = x;

console.log(x === y);
console.log(x === z);

It prints

false
true

x and y are like two identical twins: they look the same, but they're different people. x and z are the same person with two nicknames.

Reading is step one

CurlyScript turns these notes into a game: short questions, an explanation after every answer, and a test at the end of each grade. Free, with nothing to sign up for.

Start learning