The line
zoobis = zoo;
just makes both the zoobis
and the zoo
variables point at the same object. Then, the line
zoobis.animals = zoo.animals.filter((animal) => animal.color === "brown");
modifies the state of the one object both variables are pointing at, replacing its animals
property with a new filtered array.
Naturally, you see the same object state regardless of whether you look at it via zoobis
or via zoo
, as both of those variables refer to the same object.
Some ASCII-art:
Once you've created the zoo
object, you have something vaguely like this in memory:
+−−−−−−−−−−−−−−−−+
+−>| (object) |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−+
zoo:[Ref71234]−−−−−−>| (object) | | | id: 1 |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | name: "Foufou" |
| name: "Valley of monkeys" | +−−−−−−−−−−−−−−−+ | | color: "brown" |
| animals: [Ref55412] |−−>| (array) | | +−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ |
| 0: [Ref45132] |−+ +−−−−−−−−−−−−−−−−+
| 1: [Ref45174] |−−−−−−−−−−−−−−−−−−−−−−−>| (object) |
| 2: [Ref45228] |−+ +−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−+ | id: 2 |
+−>| (object) | | name: "Toutou" |
+−−−−−−−−−−−−−−−−+ | color: "brown" |
| id: 3 | +−−−−−−−−−−−−−−−−+
| name: "Moumou" |
| color: "blue" |
+−−−−−−−−−−−−−−−−+
Notice that zoo
contains a reference to the object (conceptually shown above as [Ref71234], but you never actually see the value of an object reference in code).
Then after zoobis = zoo;
you have:
zoo:[Ref71234]−−+
| +−−−−−−−−−−−−−−−−+
| +−>| (object) |
| +−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−+
+−−−>| (object) | | | id: 1 |
| +−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | name: "Foufou" |
| | name: "Valley of monkeys" | +−−−−−−−−−−−−−−−+ | | color: "brown" |
| | animals: [Ref55412] |−−>| (array) | | +−−−−−−−−−−−−−−−−+
zoo:[Ref71234]−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ |
| 0: [Ref45132] |−+ +−−−−−−−−−−−−−−−−+
| 1: [Ref45174] |−−−−−−−−−−−−−−−−−−−−−−−>| (object) |
| 2: [Ref45228] |−+ +−−−−−−−−−−−−−−−−+
+−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−+ | id: 2 |
+−>| (object) | | name: "Toutou" |
+−−−−−−−−−−−−−−−−+ | color: "brown" |
| id: 3 | +−−−−−−−−−−−−−−−−+
| name: "Moumou" |
| color: "blue" |
+−−−−−−−−−−−−−−−−+
Notice how the value of zoo
([Ref71234]) was copied into zoobis
, but that value is just a reference to the one object.
Then after [filter]:
zoo:[Ref71234]−−+
| +−−−−−−−−−−−−−−−−+
| +−>| (object) |
| +−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−−+
+−−−>| (object) | | | id: 1 |
| +−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | name: "Foufou" |
| | name: "Valley of monkeys" | +−−−−−−−−−−−−−−−+ | | color: "brown" |
| | animals: [Ref65241] |−−>| (array) | | +−−−−−−−−−−−−−−−−+
zoo:[Ref71234]−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ |
| 0: [Ref45132] |−+ +−−−−−−−−−−−−−−−−+
| 1: [Ref45174] |−−−−−−−−−−−−−−−−−−−−−−−>| (object) |
+−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+
| id: 2 |
| name: "Toutou" |
| color: "brown" |
+−−−−−−−−−−−−−−−−+
Notice how you replaced the old animals
value ([Ref55412]) with a new value ([Ref65241]) because you created and stored a new array.
If you want to copy zoo
, you can use Object.assign
or property spread (ES2018+):
zoobis = Object.assign({}, zoo);
// or
zoobis = {...zoo};
That makes a shallow copy (so for instance, both objects' animals
property points to the same array). A shallow copy is sufficient for what you've shown (but might be problematic if you have other properties on zoo
referring to objects).
If you want to make a deep copy, see this question's answers.