Because both tony
and peter
share the array, which is on person
. There's only one array, you're just changing its state.
After you've created tony
and peter
, you have this in memory (omitting details):
+−−−−−−−−−−+
person−−−−−−−−−−−−−−−−−−−+−+−−>| (Object) |
/ / +−−−−−−−−−−+ +−−−−−−−−−−−+
| | | stomach |−−−−−>| (Array) |
| | +−−−−−−−−−−+ +−−−−−−−−−−−+
| | | length: 0 |
| | +−−−−−−−−−−−+
+−−−−−−−−−−−+ | |
tony−−−−>| (Object) | | |
+−−−−−−−−−−−+ | |
| __proto__ |−−+ |
+−−−−−−−−−−−+ |
|
+−−−−−−−−−−−+ |
peter−−−>| (Object) | |
+−−−−−−−−−−−+ |
| __proto__ |−−−−+
+−−−−−−−−−−−+
Whether you access that array via tony.__proto__.stomach
or peter.__proto__.stomach
(via the prototype chain), you're accessing just that one array. When you push "shawarma"
on it via eat
, that one array's state is modifed, and visible regardless of which path you take to get to it:
+−−−−−−−−−−+
person−−−−−−−−−−−−−−−−−−−+−+−−>| (Object) |
/ / +−−−−−−−−−−+ +−−−−−−−−−−−−−−−+
| | | stomach |−−−−−>| (Array) |
| | +−−−−−−−−−−+ +−−−−−−−−−−−−−−−+
| | | length: 1 |
| | | 0: "shawarma" |
+−−−−−−−−−−−+ | | +−−−−−−−−−−−−−−−+
tony−−−−>| (Object) | | |
+−−−−−−−−−−−+ | |
| __proto__ |−−+ |
+−−−−−−−−−−−+ |
|
+−−−−−−−−−−−+ |
peter−−−>| (Object) | |
+−−−−−−−−−−−+ |
| __proto__ |−−−−+
+−−−−−−−−−−−+
You'd solve this by giving tony
and peter
their own stomach
s, and probably removing stomach
from person
(though you could leave it if you want to use person
directly as well as using it as a prototype):
let person = {
stomach: [], // You may or may not want to remove this, depending
eat(food) {
this.stomach.push(food);
}
};
let tony = {
__proto__: person,
stomach: []
};
let peter = {
__proto__: person,
stomach: []
};
tony.eat("shawarma");
console.log(tony.stomach); // shawarma
console.log(peter.stomach); // empty