4

I am hoping someone can explain how and why the answer to this question is... "Malibu".

Meet Sherlock Holmes, a world-renowned detective from London:

let sherlock = {
  surname: 'Holmes',
  address: { city: 'London' }
};

His friend, John Watson, recently moved in:

let john = {
  surname: 'Watson',
  address: sherlock.address
};

Sherlock is a brilliant detective, but a difficult flatmate. One day, John decides he’s had enough—he changes his surname and moves to Malibu:

john.surname = 'Lennon';
john.address.city = 'Malibu';

What is the answer to.... console.log(sherlock.address.city); // ?

The answer is Malibu but can anyone explain why and how it is this?

1
  • 1
    It's just because Sherlock decided to follow Watson but didn't tell you. He probably travelled under a false identity too, what a sneaky dude he is
    – Foxxxey
    Dec 5, 2022 at 18:09

1 Answer 1

3

Notice how sherlock.address is an object. The object { city: 'London' }.

The code basically assigns the exact same object to john. So, sherlock and john live in the same house, that's fine. But then when john moves, it assigns Malibu to the city of his address, which is the exact same address object that sherlock is using, hence sherlock sees the change.

To fix this, instead of assigning the exact same address object, we need to make a copy.

There are many ways in Javascript to copy an object, but let's use this simple one (the object destructuring/spread operator syntax {...ojb}):

let john = {
  surname: 'Watson',
  address: {...sherlock.address}
};

This way, instead of using the object sherlock.address as is, we copied it. After this, when john changes his city, it will not reflect to sherlock.

Another way is to declare an address object for john and copy the city, like this:

let john = {
  surname: 'Watson',
  address: {city: sherlock.address.city}
};

Spread operator vs rest operator, ..., similar syntax, different purpose:

The Spread operator is used to make a copy of an object, or merge multiple objects together (notice how it is used in the object you want to copy:

const person = {name: "John", lastName: "Doe", age: 59, email: "johndoe@gmail.com"};

const personCopy = {...person};

console.log(personCopy); // {name: 'John', lastName: 'Doe', age: 59, email: 'johndoe@gmail.com'}

// Merging objects:

const moreProperties = {city: "New York", isActive: true};

const merged = {...person, ...moreProperties};

console.log(merged); // {name: 'John', lastName: 'Doe', age: 59, email: 'johndoe@gmail.com', city: 'New York', isActive: true}

The rest operator is used to assign all the properties or the rest of the properties of an object to a variable (notice how it goes in the new variable to you to assign the rest of the properties to):

const person = {name: "John", lastName: "Doe", age: 59, email: "johndoe@gmail.com"};

// Here I'm only extracting the `name` and `lastName` properties of the object into their corresponding variables. Then, I use the rest operator `...` to assign the rest of the properties of `person` that I haven't extracted (copied) into the `restOfTheProperties` (could be named anything) variable, which is essencially a copy of all the remaining properties of the object.
const { name, lastName, ...restOfTheProperties} = person;

console.log(name); // "John"

console.log(lastName); // "Doe"

console.log(restOfTheProperties); // {age: 59, email: 'johndoe@gmail.com'}

It can also be used in function args, like this:

function etc(...args) {
    console.log(args);
}

etc(1,2,3); // [1,2,3]

Could be used for arrays too.

More info here: https://www.freecodecamp.org/news/javascript-rest-vs-spread-operators/

2
  • Thanks for the explanation. I think I see what you mean,,.. they are both pointing to the same object (address) so when one is changed it reassigns both. Still a bit fuzzy but i think i see it. As far as the fix for it... can i ask you one question? is that "destructuring" method you are using the same as a "rest parameter" or a is that something different?
    – Blockpain
    Dec 7, 2022 at 11:40
  • Similar syntax, different usage and purpose. See my update to answer. I put a couple of examples. This ... operator is also used as a varargs operator in functions so you can send multiple arguments to a function and they are going to be treated as an array of those arguments. Like function etc(...args), and would be called like etc(1,2,3); and args then would be [1,2,3]. Dec 7, 2022 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.