Beginner · Arrays and objects · topic 20 of 61 · 25 min
References, copies and equality
Explanation
Values versus references
A primitive (number, string, boolean…) is stored as the value itself. An object or array is stored somewhere in memory, and the variable holds a reference: a pointer to where it lives. Assigning an object to another variable copies the reference, not the object.
const original = { qty: 1 };
const alias = original; // same object, two names
alias.qty = 5;
console.log(original.qty); // 5=== compares identity for objects
console.log([1, 2] === [1, 2]); // false: two different arrays
const a = { x: 1 };
const b = a;
console.log(a === b); // true: the same object
console.log(JSON.stringify({ x: 1 }) === JSON.stringify({ x: 1 })); // true (compares content, key order matters)Functions receive references too
Passing an object to a function passes the reference. If the function changes the object, the caller sees the change. This is called mutation, and unexpected mutation is one of the most common bugs in real projects.
function addFreeGift(cart) {
cart.push('free keychain'); // mutates the caller's array
return cart;
}
const myCart = ['shoes'];
addFreeGift(myCart);
console.log(myCart); // ['shoes', 'free keychain'] (changed!)Shallow copies
Spread ([...arr], {...obj}), Object.assign({}, obj), arr.slice() and Array.from(arr) make a shallow copy: a new outer array or object, but nested objects inside are still shared references.
const order = { id: 1, address: { city: 'Pune' } };
const copy = { ...order };
copy.id = 2; // fine: id is a primitive in the new object
copy.address.city = 'Nashik'; // changes the SHARED nested object!
console.log(order.address.city); // 'Nashik'Deep copies with structuredClone
A deep copy duplicates every level. structuredClone(value) is built into modern browsers and Node.js 17+. It handles nested objects, arrays, Dates, Maps and Sets, but not functions or class methods.
const deep = structuredClone(order);
deep.address.city = 'Thane';
console.log(order.address.city); // 'Nashik' (unchanged this time)Object.freeze
Object.freeze(obj) stops changes to an object's own properties (in strict mode a change throws; otherwise it is ignored). The freeze is shallow: nested objects can still change. It is useful for constants such as configuration.
'use strict';
const CONFIG = Object.freeze({ gst: 18, limits: { cod: 50000 } });
// CONFIG.gst = 5; // TypeError in strict mode
CONFIG.limits.cod = 1; // allowed: freeze is shallowNeed help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
References, copies and equality · 1/6
In this lesson you will learn why objects sometimes change "by themselves", and how to copy them safely.
Prefer a video by a teacher? Find free videos on “javascript reference vs value shallow copy deep copy structuredClone” on YouTube ↗
In real life: The "discount applied twice" bug
A developer at an online store reused one product object for both the listing page and the cart. The cart code applied a discount by changing product.price directly, so the listing page also showed the reduced price and then discounted it again at checkout. The fix was to copy the product before changing it.
const product = { name: 'Lamp', price: 1000 };
const cartItem = { ...product, price: product.price * 0.9 };
console.log(product.price, cartItem.price); // 1000 900Practice (0/3 done)
addItem(cart, item) currently changes the caller's array. Make it return a NEW array with the item added, leaving the original unchanged.
Write moveOrder(order, newCity) that returns a copy of order with address.city changed. The original order, INCLUDING its nested address, must not change.
Write sameItems(a, b) that returns true when two arrays of primitives have the same items in the same order (=== on the arrays is not enough).
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Objects: keys and valuesArrays and objects · same module
- Array methods: map, filter, reduce and friendsArrays and objects · same module
- References: another name for a variableC++ Programming (modern C++ and DSA) · References, pointers, arrays and strings
- Structs, value types and reference typesC# and .NET · Classes and objects
- Objects in depthFrontend Web Development · JavaScript in depth
- Records and pattern matchingC# and .NET · Inheritance, interfaces and records
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
const a = [1]; const b = a; b.push(2); What is a?
Answer: [1, 2]
a and b refer to the same array.
What does { x: 1 } === { x: 1 } give?
Answer: false
They are two different objects, so the references differ.
const o = { inner: { n: 1 } }; const c = { ...o }; c.inner.n = 2; What is o.inner.n?
Answer: 2
Spread is shallow: inner is shared.
Which makes a deep copy that keeps Dates as Dates?
Answer: structuredClone(obj)
structuredClone copies every level and supports Dates, Maps and Sets.
What is wrong with: const std::string& name() { std::string s = "Asha"; return s; }Related
Answer: It returns a reference to a local that is destroyed: a dangling reference
s dies when the function returns. Return std::string by value.
Assigning one class variable to another...Related
Answer: Copies the reference, so both refer to the same object
Classes are reference types.
What does Object.entries({ a: 1, b: 2 }) return?Related
Answer: [['a', 1], ['b', 2]]
entries gives an array of [key, value] pairs. keys gives only the keys and values only the values.
From Objects in depth
What does == compare for two record objects?Related
Answer: Their property values
Records generate value-based equality.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- This is the last topic of “Arrays and objects”. The module exam comes next.
- Module 4 exam: Arrays and objects · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Scope, this, prototypes and classes. 61 topics left in the course before the final exam.