References & Copies

The Course
•
6 min read

Assigning an object to another variable does not copy it. Both names refer to the same object. If you edit a property through one name, reading through the other sees that change. This explains many surprising bugs in lists of records.

The spread syntax { ...original } makes a new object by copying its properties. [...items] similarly makes a new array. Later properties override earlier ones: { ...original, done: true } copies the original properties and then replaces done with true. Reversing that order lets the copied done value win instead.

Both copies are shallow: nested objects remain shared. Our study records contain only strings, numbers, and booleans, so a shallow copy is enough when making a revised record.

Do not call everything immutable just because you used const. It protects the binding—the name’s association with a value. It does not freeze an object. Decide whether your program should edit the original object or create a revised copy, and explain that choice. On Day 4 you will put these decisions inside functions.

Predict before running

Which assignment changes original? After running, explain why copy has a different duration. Try adding a nested object only as an extra experiment; notice that spread will not copy that nested object for you.

Predict, then run JavaScript
const original = { topic: "Loops", minutes: 20 };
const alias = original;

alias.minutes = 30;

const copy = { ...original };

copy.minutes = 45;
console.log(original.minutes);
console.log(copy.minutes);
Check your prediction
30
45

Trace each statement in order. If your prediction differed, describe the first place your mental model and the result diverged before trying again.

A shallow copy still shares nested objects

A spread copies the outer container, not everything reachable from it. If a property holds another object, both copies hold a reference to that nested object. Copy the nested object too when you need to change it independently.

This example uses a preferences record containing a reminder record. Draw two outer boxes and one shared inner box before running; then draw the additional inner box made for independent.

A shallow copy still shares nested objects JavaScript
const original = { reminder: { hour: 9 } };
const shallow = { ...original };

shallow.reminder.hour = 10;
console.log(original.reminder.hour);

const independent = { ...original, reminder: { ...original.reminder } };

independent.reminder.hour = 11;
console.log(original.reminder.hour);
console.log(independent.reminder.hour);
Check your prediction
10
10
11

The first copy shares reminder. The second explicitly makes a new reminder object before changing hour.

Equality asks about identity for objects

Two separately created objects with identical properties are not strictly equal. The comparison asks whether they are the same object, not whether their contents match. For a small test, compare the specific properties you care about. Later you can learn a test framework’s deep-equality tools.

Predict on paper: const a = { score: 1 }; const b = a; const c = { score: 1 }; Which of a === b and a === c is true? Run your experiment, then change b.score and inspect all three. State whether you intended a shared update or an independent value before choosing your copying technique.

For now, practise copying our flat records: their properties hold strings, numbers, and booleans rather than other objects. The nested example explains a limit of spread; you do not need to memorize a technique for copying every possible structure.

A shallow copy does not copy nested records

A spread creates a new outer record or array. It copies the references stored inside it, so nested objects can still be shared. To isolate a nested update, copy every object along the path you intend to change. Do not call a shallow copy an independent snapshot of all data.

Use identity comparisons to ask whether two names refer to the same object, and value comparisons to ask what data it contains. These are different questions. A useful update can allocate a new outer container while intentionally retaining unchanged records.

The nested value is still shared JavaScript
const before = { topic: "Loops", detail: { minutes: 20 } };
const shallow = { ...before };

shallow.detail.minutes = 30;
console.log(before.detail.minutes);
console.log(shallow === before);
console.log(shallow.detail === before.detail);
Check your prediction
30
false
true

The outer records differ, but both detail fields point to one nested record. Changing that nested record is visible through either outer record.

Copy the path you change JavaScript
const before = { topic: "Loops", detail: { minutes: 20 } };
const after = { ...before, detail: { ...before.detail, minutes: 30 } };

console.log(before.detail.minutes);
console.log(after.detail.minutes);
console.log(after.detail === before.detail);
Check your prediction
20
30
false

There are now two detail records. This is an explicit two-level copy for this shape, not a general deep-copy algorithm. More complicated data needs a deliberate ownership policy.

Try the rule on new inputs

Try a nested list as well as a nested object. Draw boxes and arrows for both examples before changing data. Identify the exact object that must be copied to preserve the original minutes.

Your turn

Exercise

References & Copies: practise

Make a completed copy of a session while leaving the original incomplete. Print false, then true. Do not mutate the original.

Your working space JavaScript
const session = { topic: "Arrays", minutes: 25, done: false };
// Create completed, then print both done properties.
Hint 1: the idea

You need a new object, not another name for the same one.

Hint 2: a first step

Spread session into a new object and write done: true after the spread.

Show one solution
const session = { topic: "Arrays", minutes: 25, done: false };
const completed = { ...session, done: true };

console.log(session.done);
console.log(completed.done);
false
true

Later properties override earlier ones. Writing done: true before the spread would let the original false overwrite your change.

What you should be able to explain

  • What exactly is copied by spread?
  • Draw the shared nested reference in the example.
  • Why does identical-looking content not guarantee object equality?

Was this article helpful?

Your response is saved on this device.