ما صرفا یک شیئ pizza ایجاد کردیم که هیچ پراپرتی ندارد و انتظار داریم خروجی مقدار برابر باشد ولی اینگونه نیست. با مفاهیمی که تا بحال آموختیم نمیتوانیم تصور کنیم که چه کدهایی قبل از این دو خط میتواند موجب این اتفاق شود پس مدل ذهنی ما کامل نیست. برای حل این معما در این مطلب به شرح prototypes میپردازیم. و از همه مهمتر اینکه prototypes قلب چندین ویژگی مختلف جاوااسکریپت هستند. معمولا افراد به یادگیری این مفهوم کم توجهی میکنند زیرا این مفهوم از نظر آنها خیلی غیر عادی به نظر میرسد درصورتی که مفهومی که در آن نهفته است بسیار سادهاست.
Prototypes
مفهوم prototypes را به همراه مثالهای زیر و مدل ذهنی که تا بحال آموختیم شرح خواهیم داد.به کد زیر و مدل ذهنی آن توجه کنید. در مثال بالا شیئ که gwen به آن متصل است پراپرتی teeth را ندارد پس در نتیجه خروجی کد زیر undefined خواهد بود. فرض کنیم میخواهیم به جاوااسکریپت بگوییم در صورتی که یک پراپرتی در یک شیئ مثل پراپرتی teeth در شیئ gwen وجود نداشت به دنبال آن پراپرتی در یک شیئ دیگری مانند human بگردد و مقدار آن را برگرداند، این دقیقا همان مفهوم prototype است.
ما با تعریف یک پراپرتی به نام کلیدی proto مشخص میکنیم که درصورت پیدا نشدن یک پراپرتی در یک شیئ جاوااسکریپت برای یافتن آن در کدام شیئ دیگری میتواند جستوجو کند. به مثال زیر توجه کنید. مدل ذهنی قطعه کد بالا در نتیجه پس از این تغییرات خروجی کد زیر برابر 32 میشود. نگاه دقیقتر به فرایندی که شرح دادیم.
مفهوم The Prototype Chain
مفهوم زنجیره prototype به این اشاره میکند که جاوااسکریپت عملیات جستوجو در prototype را مشابه شئ اول را همیشه تکرار میکند و زمانی متوقف میشود که یا آن پراپرتی را پیدا کند و یا مقدار proto یک شیئ تعریف نشده باشد.مثال زیر نمونهای از این مفهوم زنجیره prototype است.
پراپرتی اصلی یک آبجکت یا یک Prototype
برای تشخیص این مورد کافیست از متد hasOwnProperty استفاده کنیم در صورتی که پراپرتی در آبجکت موجود باشد مقدار ture در غیر اینصورت مقدار false را برمیگرداند. همانطور که قبلا اشاره کردیم مفهوم prototype صرفا به مفهوم جستوجوی جاوااسکریپت برای یافتن یک مقدار اشاره دارد و نه چیزی بیشتر پس با توجه به آنچه تا بحال آموختیم با عملیات انتصاب فقط پراپرتی جدید teeth در شیئ gwen ایجاد شده و به مقدار 31 متصل میشود.The Object Prototype
به شیئ زیر توجه کنید، هیچ prototype ای برای آن تعریف نکردیم درسته؟ حال قطعه کد زیر را در console مرورگر خود اجرا کنید. با کمال تعجب مقدار proto برابر undefined یا null نیست بلکه شامل مقادیر مختلفی مانند تابع toString و hasOwnProperty و ... است. با این اوصاف اونطور که ما تصور کردیم ما با استفاده از صرفا یک شیئ خالی ایجاد نکردیم بلکه جاوااسکریپت بصورت پیش فرض یک پراپرتی proto تعریف کرده که به شیئ ای اشاره میکند که به آن The Object Prototype میگوییم. برای ایجاد یک آبجکت بدون prototype پیش فرض زمان تعریف آن میتوان مقدار proto را برابر null قرار داد.آلوده کردن prototype یا Polluting the Prototype
همانطور که تا الان متوجه شدیم تمام object ها بصورت پیش فرض شامل یک پراپرتی proto هستن که به یک شیئ که نام آن را The Object Prototype گذاشتیم اشاره میکند. به کد زیر توجه کنید. با این کار ما تغییراتی در prototype پیش فرض ایجاد کردیم که prototype پیش فرض تمام object هایی بوده که تا بحال ساختهایم و که نتایج زیر را به دنبال دارد. تغییر دادن prototype مشترک بین object های مختلف را آلوده کردن prototype یا Polluting the Prototype میگویند. در گذشته برای افزودن ویژگیهای سفارشی جدید به جاوااسکریپت از این روش بسیار استفاده میشد ولی با گذشت سالها جامعه وب متوجه شدن که اینکار باعث ایجاد شکنندگی میشود و اضافه کردن قابلیتهای جدید زبان را دشوارتر میکند و ترجیح دادن از آن دوری کنند. حالا شما میتونید معمای مثال اول را حل کرده و در console مرورگر نتایج را تست کنید.proto یا prototype
ممکن است شما عناوین صفحهی MDN را مشاهده کنید و برای شما سوال پیش بیاید که پراپرتی prototype چیست. خبر بد: prototype تقریبا هیچ ربطی به مفهوم prototypes و proto که تا بحال راجع به آن صحبت کردیم ندارد بلکه مرتبط با عملگر new در جاوااسکریپت است. پس به یاد داشته باشید proto همان نمونهی اولیه یا یک prototype از یک شیئ است.در صورتی که پرارپتی prototype یک شیئ و عملگر new دو مفهوم کاملا مجزا هستند.