Content updated
By the end, you can…
- Assignment shares an object. Spread copies one outer level; nested objects may still be shared.
- Predict the example's result, change one part, and verify the behavior in your own script.
One idea at a time
Objects have identity. Two separate object literals produce distinct objects even when their property values match. Assigning one object to another variable instead shares the original. These names are aliases: changing a property through either name changes the same object. Draw two arrows to one box when tracing an alias.
A method is a function called through an object. For an ordinary function, this depends on how the function is called. In learner.describe(), this refers to learner. It is not permanently tied to the object where the function was first written. Arrow functions use the surrounding this instead, so they are not interchangeable with ordinary methods.
What to remember first
Assignment shares an object. Spread copies one outer level; nested objects may still be shared.
Read the code before trying it
const second = firstShare the same object- No new object is made. first === second is true because they have the same identity.
{ ...first }Copy the outer properties- A new outer object is created, but object-valued properties still point to the same nested objects.
this.nameRead from a call receiver- In an ordinary method called as learner.describe(), the receiver is learner.
Object.create(parent)Set a prototype- A prototype is another object used as a fallback during property lookup. Properties absent on the new object can be looked up on parent. Some objects have null prototypes instead.
new Learner(name)Call a constructor- new creates an object and calls the constructor with that object as this. Shared methods can live on Learner.prototype.
Walk through an example
const original = { settings: { theme: "light" } };
const copy = { ...original };
copy.settings.theme = "dark";
console.log(original === copy);
console.log(original.settings === copy.settings);
console.log(original.settings.theme);The outer identity comparison is false because spread created a new outer object. The nested identity comparison is true because both settings properties point to one object. Updating theme through copy therefore changes what original.settings reads. A shallow copy did happen; its boundary simply stopped before the nested object.
See it happen: try a small change
Predict the result, choose a version, then compare the code and output. Try the controls when the example has them. Each version starts fresh.
Code to notice
const original = { settings: { theme: "light" } };
const copy = { ...original };
copy.settings.theme = "dark";
console.log(original.settings.theme);Live result
What changed: The nested object is shared, so the original now reads dark.
Look a little closer
To change the nested theme independently, copy settings too: { ...original, settings: { ...original.settings, theme: 'dark' } }. This copies exactly the levels you intend to change. Other deeper references would still be shared. Do not describe this as a universal deep copy of every possible data structure.
Prototype lookup lets objects share behavior. A property on the object itself takes precedence over an inherited property with the same name. You do not need constructors for every small record; plain object literals are enough for many tasks. Learn to recognize prototype-based examples without adding an inheritance structure to a simple form unnecessarily.
Follow the receiver and a shared method
Predict the result, choose a version, then compare the code and output. Try the controls when the example has them. Each version starts fresh.
Code to notice
function describe() {
return this.name;
}
const first = { name: "Mia", describe };
const second = { name: "Sam", describe };
console.log(first.describe());
console.log(second.describe());Live result
What changed: The same ordinary function reads a different this because each call has a different receiver.
Try it in your own project
Start fresh with the shallow-copy example. Then replace it with the version that also copies settings. Log both themes and both identity comparisons. Use the method-receiver preview before writing the two-object method task.
The interactive preview runs in its own isolated document. Its Output panel mirrors console.log messages; it is not a full DevTools console. Choosing another version or resetting starts a fresh example and does not edit your local files. Read any simulation label: storage and request demonstrations explain their offline substitutes, while the written local examples use the real browser APIs.
A common wrong turn
A method pulled into a standalone variable loses its original receiver. Strict mode is a stricter set of language rules enabled with "use strict" at the start of a script or function. There, an ordinary standalone call has undefined this; in a non-strict browser script it can instead use the global object. Prefer calling it through the intended object, or deliberately bind a receiver when needed. Never assume this means the function's permanent owner.
Your turn: understand methods, references, and object copies
Make a separate settings update while keeping the original theme unchanged.
Optional exploration
Try the related prediction challenge below, or run the task above in your own script. The challenge asks you to choose an output and explains the result.
- Run the shallow-copy example and predict why the original becomes dark.
- Copy both the outer object and settings before changing theme. Check that the original stays light.
- Create an ordinary describe method using this.name and call it through two objects. Explain why the receiver changes the output.
Go to the source
Examples are authored for Tuklas and checked with code and reference documentation. This is not a claim of independent human review. Suggest a correction.