Mohammad Bohluli
Mohammad Bohluli
خواندن ۵ دقیقه·۴ ماه پیش

قسمت ششم (all about inheritance in js)

توی این قسمت هر آنچه از ارث بری رو که بلد بودم، یکجا جمع کردم که درکش راحت تر باشه

توی جلسات قبلی(لینکشون توی پروفایلم هستن) راجع به prototype inheritance صحبت کردیم

و سه تکنیک ساخت برنامه شی گرا با constructor function و ES6 Class و Object.create رو یاد گرفتیم و همشون این اجازه رو به آبجکت میدن که متد ها و پراپرتی هارو توسط prototype رو به ارث ببره

اما چیزی که توی این مقاله میخواییم بگیم، ارث بری بین کلاس هاست نه ارث بری prototype و حواستون باشه این دوتا یعنی ارث بری بین دوتا کلاس و ارث بری prototype رو باهم اشتباه نگیرید.

توی ارث بری کلاس ها، به کلاس والد parent یا class میگن و به کلاس فرزند child یا subclass میگن




اول بریم ارث بری رو توی constructor function بررسی کنیم:

مثال زیر رو دقت کنید، دوتا constructor داریم یکی Person که میشه کلاس والد و یکی Student که میشه کلاس child ما و هرکدوم از این ها هم متد و پراپرتی خودشونو دارن(خط به خط کد زیر رو توضیح خواهم داد فقط زیر چشمی نگاهتون بهش باشه 😏)

constructor function example
constructor function example


توی کلاس Student ما نیاز به firstName و birthday داریم اما اگه بیاییم مثل کلاس والد باز تعریفشون کنیم اصل DRY رو زیر پا میزاریم و کد تکراری میشه پس از متد call برای به ارث بردنشون از کلاس والد استفاده میکنیم

خب تا اینجای کار دوتا کلاس، constructor اشون باهم مچ شدن ولی method هاشون چی ؟ چطوری کلاس فرزند متد های کلاس والد رو به ارث ببره و بتونه بهشون دسترسی داشته باشه ؟

فقط کافیه prototype هاشون رو با خط شماره 17 توی مثال به هم وصل کنیم با این کار کلاس فرزند هر آنچه که کلاس والد داره رو به ارث میبره

حالا یه سوال ممکنه پیش بیاد، چرا از Object.create استفاده کردیم؟ خب میشه توسط خط 19 پروتوتایپ والد رو بریزیم توی فرزند دیگه چکاریه آخه از Object.create استفاده کنیم 🤔

یکم عمیق ترمون نشه😉 ؟؟؟ (دیاگرام زیر رو ببینید) اگه به جای Object.create از خط 19 استفاده کنیم، داریم به جاواسکریپت میگیم که بیا پروتوتایپ والد(Person) رو بزار توی پروتوتایپ فرزند(Student) پس عملا این وسط داریم Student.prototype رو حذف میکنیم و prototype chain (آموزش prototype chain) ما از بین میره،

فقط کافیه یه بار خط 19 رو بزارید توی کد هاتون یه بارم با Object.create امتحان کنید و از mike لاگ بگیرید تا بهتر درکش کنید چه اتفاقی میوفته اگه از خط 19 استفاده کنیم پس کلا فراموشش کن خط 19 رو

خب حالا وقتی یه متد از متد های Person رو روی mike که از Student ساخته شده صدا کنیم، جاواسکریپت چطور این متد رو پیدا میکنه ؟( بازم دیاگرام زیر رو هنگام توضیحات ببینید)

وقتی mike.calcAge() رو صدا میزنیم، جاواسکریپت اول از همه میره _ _ proto_ _ آبجکت mike رو میگرده اگه پیدا کرد که هیچی اگه پیدا نکرد میره سمت پروتوتایپ Student اگه بازم پیدا نکرد میره پروتوتایپه Person رو میگرده و اگرم پیدا نشد هیچی null برمیگرده.

این است قدرت prototype chain 😎

نکته : فقط یه مشکل کوچولویی پیش میاد این وسط اینه که وقتی خط زیر رو لاگ بگیرید

Student.prototype.constructor

میاد constructor عه Person رو نشون میده پس با کد زیر این مشکل رو حل میکنیم

Student.prototype.constructor = Student

حالا دیگه constructor عه Student رو نشون میده

نکته: اگه بخواییم یک متد از Person رو توی کلاس Student به اصطلاح override کنیم یعنی باز نویسیش کنیم باید دقیقا اسم همون متد رو بنویسیم و بعدشم لاجیک مربوطه رو پیاده سازی کنیم و چون فهمیدید javascript چطور یه متد رو پیدا میکنه پس دیگه میبینه خود Student اون متد رو داره پس دیگه سراغ والد نمیره



بریم ارث بری توی ES6 Class رو بررسی کنیم:

همون طور که توی قسمت های قبلی مقاله های شی گرایی گفتم، جاواسکریپت چیزی به اسم class نداره و این class که توی ES6 اضافه شده فقط یه پوسته اس و پس قضیه توسط constructor function ها هندل میشه بنابراین، ارث بری توی ES6 Class دقیقا همین اتفاقات بالا رخ میده فقط از نظر سینتکسی فرق میکنه

مثال زیر رو ببینید و مقایسه اش کنید با ورژن constructor function اش که بالاتر مثالش هست

همه چیز کاملا شفافه فقط چندتا نکته راجع به کد بالا بگم:

توی ES6 Class برای ارث بری بین کلاس والد و فرزند به جای خط زیر از کلمه کلیدی extends استفاده میکنیم

PersonProto.init.call(this, firstName, birthday);

تابع constructor هم که معلومه چیکار میکنه و برای اینکه از مقادیر constructor تابع والد بخواییم استفاده کنیم اومدیم به جای متد call از کلمه کلیدی super استفاده کردیم و کلمه کلیدی Super هم اسمش با خودشه میاد از superclass یعنی کلاس والد مقادیر رو میگیره



و اما آخرین نوع ارث بری هم مربوط میشه Object.create

اگه نمیدونید چیه و چطور کار میکنه این مقاله رو بخون، اگرم میدونی چیه که خب مثال زیر رو ببین تا توضیح بدم ارث بری چطوری داخلش هندل میشه

خب توی خط اول اومدیم یه پروتو برای Person ساختیم به اسم PersonProto و توسط Object.create ازش یک آبجکت ساختیم و ریختیمش توی steven حالا استیون یک شی هست که proto اش، PersonProto هست(تابع init حکم constructor رو بازی میکنه ولی اصلا خاصیت یک constructor رو نداره تو مقاله قبل گفتمش)

حالا میخواییم یه کلاس فرزند داشته باشیم به اسم Student که تمام ویژگی های کلاس والدش یعنی Person رو داشته باشه

خب کاری نداره که توی خط 14 باز از همون پروتوعه Person استفاده کردیم و به همین راحتی کل ویژگی هارو به ارث میبره و خب مثل مثال های قبل توی خط 16 اومدیم init رو override کردیم و توی خط 21 هم کلا یه متد جدید به Student اضاف کردیم

حالا jay توی خط 25 یک شی هست که از proto اش StudentProto هست و به تمام متد های PersonProto دسترسی داره (به خاطر خط 14)

دیاگرام زیر هم به صورت شهودی داره میگه که ارث بری توی Object.create چطور کار میکنه

این شد کل ارث بری توی جاواسکریپت، چیزی نمونده بود که نگم و تا جایی که تونستم چیزایی که یاد گرفتم رو یک جا جمع کردم که مرجع خوبی بشه


امیدوارم بدردت خورده باشه❤️

کانال تلگرامم 👈 LeanByLearn@

شی گرایی جاوااسکریپتجاوا اسکریپتPrototypal Inheritanceارث بری در جاوا اسکریپتبرنامه نویسی
علاقمند به تکونولوژی و هرچی که بهش مربوطه، کانال تلگرام LearnByLearn@
شاید از این پست‌ها خوشتان بیاید