Kenapa kedua hamster kenyang?
Kita memiliki dua hamster: speedy
dan lazy
yang mewarisi objek hamster
.
Ketika kita memberi makan salah satunya, yang satunya lagi akan ikut kenyang. Kenapa? Bagaimana cara memperbaikinya?
let hamster = {
stomach: [],
eat(food) {
this.stomach.push(food);
}
};
let speedy = {
__proto__: hamster
};
let lazy = {
__proto__: hamster
};
// Yang satu ini menemukan makanan
speedy.eat("apple");
alert( speedy.stomach ); // apple
// Yang ini juga memilikinya, kenapa? perbaikilah.
alert( lazy.stomach ); // apple
Kita perhatikan baik-baik pada apa yang terjadi dalam pemanggilannya speedy.eat("apple")
.
-
Metode
speedy.eat
ditemukan dalam prototype (hamster
), lalu dieksekusi denganthis=speedy
(objek sebelum titik). -
Lalu
this.stomach.push()
perlu menemukan propertistomach
dan panggilpush
didalamnya. Itu akan mencatistomach
didalamthis
(=speedy
), tapi tidak menemukan apapun. -
Lalu akan mengikuti rantai prototype dan menemukan
stomach
didalamhamster
. -
lalu akan memanggil
push
didalamnya, menambahkan makanan kedalam stomach dari prototype.
Jadi semua hamster membagi satu stomach!
Diantara lazy.stomach.push(...)
dan speedy.stomach.push()
. properti stomach
ditemukan didalam prototype (sebagaimana tidak didalam objeknya sendiri) , lalu datanya akan dimasukan.
Perhatikan bahwa hal tersebut tidak akan terjadi pada assignment sederhana this.stomach=
:
let hamster = {
stomach: [],
eat(food) {
// masukan this.stomach daripada this.stomach.push
this.stomach = [food];
}
};
let speedy = {
__proto__: hamster
};
let lazy = {
__proto__: hamster
};
// Speedy one menemukan makanannya
speedy.eat("apple");
alert( speedy.stomach ); // apple
// Perut Lazy one kosong
alert( lazy.stomach ); // <nothing>
Sekarang semuanya berjalan dengan baik, karena this.stomach=
tidak melakukan pencarian stomach
. Nilainya ditulis langsung kedalam objek this
.
Kita juga bisa benar-benar menghindar dari masalah dengan memastikan bahwa setiak hamster memiliki perut mereka masing-masing:
let hamster = {
stomach: [],
eat(food) {
this.stomach.push(food);
}
};
let speedy = {
__proto__: hamster,
stomach: []
};
let lazy = {
__proto__: hamster,
stomach: []
};
// Speedy one menemukan makanan
speedy.eat("apple");
alert( speedy.stomach ); // apple
// Perut Lazy one kosong
alert( lazy.stomach ); // <nothing>
Sebagai solusi umum, seluruh properti yang dideskripsikan dari objek tertentu, seperti stomach
diatas, seharusnya ditulis kedalam objeknya. Untuk menghindari masalah seperti itu.