توضیح ساده prototype در جاوا اسکریپت

جاوا اسکریپت و ارث بری مخصوص به خودش!
جاوا اسکریپت و ارث بری مخصوص به خودش!

در جاوا اسکریپت چند تا مبحث پایه ای وجود داره که در ابتدا فهم اونها کمی سخته و باعث میشه بعضی موقع ها واقعا گیج بشیم و یه حرفایی هم پشتش بزنیم :D

یکی از اون مباحث قطعا ارث بری و بحث prototype هست، همون طوری که می دونید کلی آموزش هم توی این زمینه وجود داره که البته من خودم اوایل هر کدوم رو می خوندم بیشتر گیج می شدم، شاید چون خیلی زیادی توضیح داده بودن شایدم البته من گیج بودم نمیدونم ;)!! این پست رو نوشتم تا سعی کنم به زبان ساده، فقط prototype رو توضیح بدم!

خوب ما توی برنامه خودمون نیاز به ارث بری داریم، این کار توی جاوا اسکریپت بیشتر از طریق prototype انجام می شه و نه مثل اکثر زبان ها با class، البته به نظر بعد از یک مدت کار با اون خیلی هم چیز باحال تری هست!(می دونم جاوا اسکریپت class هم داره :دی)

هر object در جاوا اسکریپت قطعا prototype داره و فقط هم یک prototype داره نه بیشتر!

حالا این prototype چیه؟ prototype رو یک property به اسم __proto__ در object خودتون در نظر بگیرید که فقط ۲ نوع مقدار میتونه بگیره:

  1. مقدار null
  2. یک object دیگر

پس همه object های شما یک property به اسم __proto__ دارند.

این property مثل والد برای object شما هستش، پس می تونیم property های اون رو به راحتی صدا بزنیم!‌ چطوری؟

وقتی property یک object را صدا می زنیم چه اتفاقی می افته؟

برای مثال obj.name رو داریم:

ابتدا در obj دنبال name می گرده اگر نبود میره توی prototype از obj و دنبال اون می گرده و اگه بود که صداش می کنه و اگر نبود باز هم به صورت تکرار پذیر سراغ prototype از prototype بعدی می رود تا در نهایت prototype دیگری وجود نداشته باشد و اگر پیدا نکرد خطا می ده!

به صورت تکرار پذیر سراغ prototype از prototype بعدی می رود
به صورت تکرار پذیر سراغ prototype از prototype بعدی می رود


از اونجایی که برنامه نویس فقط با دیدن کد یاد می گیره، توضیح کافیه و بریم توی کد ببینیم:

بررسی افزودن prototype
بررسی افزودن prototype


طبق توضیحات بالا ما ۲ تا object داریم به نام های person و staff که person رو به عنوان prototype برای staff طبق کد زیر اضافه کردیم:

staff.__proto__ = person;

همون طوری که مشخص هست شئ staff دارای greeting نیست اما ()staff.greeting اجرا شد و خطا نگرفتیم، دلیلش این بود که person رو به عنوان prototype به staff دادیم پس از اون ارث بری کرد یعنی بعد از اینکه توی staff این property وجود نداشت رفت و در person دنبال اون گشت.


استفاده از ()Object.create برای مشخص کردن prototype

در production نباید از __proto__ استفاده کرد چون در interface اصلی جاوا اسکریپت تا قبل از ES6 به صورت رسمی وجود نداره و به روش زیر باید prototype رو به object بدیم:

استفاده از Object.create به جای __proto__
استفاده از Object.create به جای __proto__


پیش فرض prototype برای object ها

به صورت پیش فرض جاوا اسکریپت Object.prototype رو به عنوان prototype تمام object هایی که می سازیم تعریف میکنه:

بررسی prototype پیش فرض
بررسی prototype پیش فرض

همان طوری که میدونیم Object.prototype یک سری property های پرکاربردی مثل hasOwnProperty و ... تو خودش داره که در زیر می بینید:

Object.prototype
Object.prototype


ساخت object از روی constructor function و یک تفاوت

اما یک استثنا خیلی معروف وجود داره اون هم ساخت object از روی constructor function هاست که دیگه Object.prototype رو به عنوان prototype خودشون ندارند:

ساخت object با استفاده از constructor function
ساخت object با استفاده از constructor function


توی این حالت prototype یک object هست که به عنوان constructor توی خودش تابعی که از روش object ساختیم رو داره:

بررسی prototype یک object ساخته شده از روی constructor function
بررسی prototype یک object ساخته شده از روی constructor function


همون طوری که توی کد مشخص هست داخل __proto__ به عنوان proto برای این object هم Object.prototype رو داریم .

به نظر این مباحث نکات اصلی در مورد prototype بود که نوشتم اگر چیزی رو به نظرتون باید اضافه کنم در کامنت ها بنویسید ;)