چرا هر دو دو همستر سیر هستند؟
ما دو همستر داریم: speedy
و lazy
که از شیء عمومی hamster
ارثبری میکنند.
زمانی که ما به یکی از آنها غذا میدهیم، دیگری هم سیر میشود. چرا؟ چگونه میتوانیم این مشکل را رفع کنیم؟
let hamster = {
stomach: [],
eat(food) {
this.stomach.push(food);
}
};
let speedy = {
__proto__: hamster
};
let lazy = {
__proto__: hamster
};
// این همستر غذا را پیدا کرد
speedy.eat("سیب");
alert( speedy.stomach ); // سیب
// این همستر هم غذا را دارد، چرا؟ لطفا این را درست کنید.
alert( lazy.stomach ); // سیب
بیایید با دقت نگاه کنیم که در فراخوانی speedy.eat("سیب")
چه اتفاقی میافتد.
-
متد
speedy.eat
درون پروتوتایپ (=hamster
) پیدا شده، سپس باthis=speedy
اجرا میشود (شیء قبل از نقطه). -
سپس
this.stomach.push()
باید ویژگیstomach
را پیدا کند وpush
را روی آن فراخوانی کند. به نظر میرسد این متد درونthis
(=speedy
) به دنبالstomach
میگردد، اما چیزی پیدا نشد. -
سپس زنجیره پروتوتایپ را دنبال میکند و
stomach
را درونhamster
پیدا میکند. -
سپس
push
را روی آن فراخوانی میکند، که غذا را به stomach درون پروتوتایپ اضافه میکند.
پس تمام همسترها شکم (stomach) یکسانی را به اشتراک میگذارند!
هم برای lazy.stomach.push(...)
و speedy.stomach.push()
، ویژگی stomach
درون پروتوتایپ پیدا شده است (چون درون خود شیء وجود ندارد)، سپس داده جدید به داخل آن فرستاده میشود.
لطفا توجه کنید که در صورت وجود یک مقداردهی ساده this.stomach=
چنین چیزی اتفاق نمیافتد:
let hamster = {
stomach: [],
eat(food) {
// this.stomach.push به جای this.stomach برابر قرار دادن با
this.stomach = [food];
}
};
let speedy = {
__proto__: hamster
};
let lazy = {
__proto__: hamster
};
// غذا را پیدا کرد Speedy همستر
speedy.eat("سیب");
alert( speedy.stomach ); // سیب
// خالی است Lazy شکم همستر
alert( lazy.stomach ); // <هیچی>
حالا همه چیز به درستی کار میکند، چون this.stomach=
در جست و جوی stomach
نیست. مقدار به صورت مستقیم درون شیء this
نوشته میشود.
همچنین میتوانیم با اطمینان از اینکه هر همستر stomach خودش را دارا میباشد از این مشکل جلوگیری کنیم:
let hamster = {
stomach: [],
eat(food) {
this.stomach.push(food);
}
};
let speedy = {
__proto__: hamster,
stomach: []
};
let lazy = {
__proto__: hamster,
stomach: []
};
// غذا را پیدا کرد Speedy همستر
speedy.eat("سیب");
alert( speedy.stomach ); // سیب
// خالی است Lazy شکم همستر
alert( lazy.stomach ); // <هیچی>
به عنوان یک راهحل عام، تمام ویژگیهایی که وضعیت یک شیء خاص را توصیف میکنند، مانند stomach
بالا، باید درون همان شیء نوشته شوند. این کار از بروز مشکلات جلوگیری میکند.