چرا هر دو دو همستر سیر هستند؟
ما دو همستر داریم: 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 بالا، باید درون همان شیء نوشته شوند. این کار از بروز مشکلات جلوگیری میکند.