داستان Prototypal Inheritance در جاوااسکرپیت به زبان خیلی ساده

من خودم شدیدا از خوندن متن های طولانی متنفر هستم و تا حد ممکن سعی میکنم طولانی هم ننویسم، اما احتمالا این متن به دلایل فنی طولانی میشه ولی امیدوارم خوندنش خسته کننده نباشهصلب مسئولیتتو این متن سعی شده مسئله Prototypal Inheritance در javascript بصورت خیلی ساده و روان بیان کنم، بنابراین ممکنه از گفتن برخی مسائل بصورت فنی تخصصی اجتناب شده باشه و برخی چیزها به بیان خیلی عامیانه گفته شده باشهمطلب خوبی به فارسی پیدا نکردم وگرنه احتمالا منم نمی نوشتم :))قطعا شما سوادتون از من بیشتره :))غلط دیکته ای های بنده رو به بزرگی خودتون ببخشیدخود Inheritance چیه اصلا ؟خب قطعا اگر قبلا با یکی از زبان های برنامه نویسی شی گرا ( object oriented) کار کرده باشید میدونید که یکی از اصول این مدل برنامه نویسی همین ارث‌بری یا Inheritance هست. به بیان ساده وقتی یک instance object از یک class میسازید و یا زمانی که یک class رو از یک class دیگر extend می کنید، اون object و class جدید تمام methodها و propertyهای کلاسِ مادر رو به ارث می‌برند و میتونن از اونها استفاده کنن، علاوه بر این خود اینها میتونن یکسری متد و خصوصیت جدید برای خودشون داشته باشند و یا method ها و propertyهای ارث برده شده رو برای خودشون override کنند.حالا Prototype چی میگه ؟خب javascript ( یا همان بیشعور بزرگ ) چیزی به اسم class نداره/نداشت ( تا قبل از ES6 ) و برای اینکه بدونیم Prototype چیه ، از اینجا شروع میکنیم که :تو javascript برای پیاده کردن class از function ها استفاده میشدفانکشن‌هایی که برای ایجاد یک instance object از اونها از دستور new استفاده میشه، فانکشن‌های سازنده یا constructor functions گفته میشن، به کد زیر دقت کنید:function myFunc(){ // constructor functions this.myProperty = "My Property "; } var myObj = new myFunc();همه functionها ( حتی اونایی که هیچ کاری نمیکنن و خالی هستن ) تو javascript خودشون object هستندهمه functionها تو javascript بدون اینکه شما براشون چیزی تعریف کنید یا بدونید، بصورت پیشفرض یک property مخفی به اسم prototype دارند ( که یک object برمیگردونه ) مثل کد زیر می تونید بهشون دسترسی پیدا کنید :function hichi(){ // I do nothing } console.log(typeof hichi.prototype); // object شما میتونید methodهای دلخواه خودتون رو به prototype یک فانکشن اضافه کنید:function myFunc(){ this.myProperty = "My Property "; } myFunc.prototype.myMethod = function() { console.log('this is my method'); };و اگر از اون فانکشن یک instance object بسازید، آبجکت جدید ما میتونه به متدهای prototype اون فانکشن مادر دسترسی داشته باشه : function Mom(){ this.momProperty = "My Property "; } Mom.prototype.speak= function() { console.log("I'm speaking"); }; var child= new Mom(); child.speak(); // I'm speakingدقت کنید در قطعه کد بالا child صرفا از طریق مادرِ خودش یعنی Mom به متد speak دسترسی داره و در واقع speak در child.prototype وجود نداره به عبارتی :child.hasOwnProperty('speak') === false) که تو javascript به این مدل ارث‌بری میگیم Differential Inheritanceخب Object.create چیکار میکنه ؟این فانکشن هم که از es5 اضافه شده، یک آبجکت خالی برای ما میسازه که به متدها و خصوصیات فانکشن مادرش دسترسی داره به این قطعه کد دقت کنید : var parent = { foo: function() { console.log(‘bar’); } }; var child = Object.create( parent ); child.hasOwnProperty(‘foo’); // false child.foo(); // ‘bar’بریم سراغ مثال‌های جدی تربه قطعه کد زیر دقت کنید : function Rectangle( width, height ) { this.width = width; this.height = height; } Rectangle.prototype.area = function() { return this.width * this.height; }; var mrect = new Rectangle( 3, 4 ); mrect.area(); // 12دیدید که چطوری mrect از Rectangle ارث‌بری میکنه، حالا فرض کنیم ما یک فانکشن سازنده دیگه به اسم Square داریم function Square( length ) { this.width = this.height = length; }حالا چیکار کنیم که Square از Rectangle ارث‌بری کنه ؟ (دقت کنید Square دیگه یک آبجکت خالی نیست) خیلی ساده است : Square.prototype = Object.create( Rectangle.prototype );از این به بعد تمام instanceهایی که از Square ساخته بشن از خود Square ارث می‌برن و چون Square از Rectangle ارث برده، همه اونها به متدها و خصوصیات Rectangle دسترسی خواهند داشت : var mInstance= new Square( 4 ); mInstance.area(); // 16خب تقریبا کلیت چیزی که باید میدونستیم همینهحالا __proto__ ماجراش چیه ؟ببین شما تو فانکشنِ Parentخصوصیتِ prototype رو دارید، زمانی که بچه به دنیا میاد :) یعنی child از parent ساخته میشه خصوصیت __proto__ در child معادل prototype در Parent میشه با کد توضیح بدم بهتر می فهمید :function Parent(){ this.name = "parent"; } var child = Object.create( Parent.prototype ); console.log( Parent.prototype === child.__proto__ ); // trueیک مثال بهتر : function Parent(y) { this.y = y; } Parent.prototype.x = 10; Parent.prototype.speak= function (z) { return this.x + this.y + z; }; var child= new Parent(20); child.speak(30); // 60 console.log( child.__proto__ === Parent.prototype, // true child.__proto__.speak=== Parent.prototype.speak, // true child.__proto__.speak=== child.speak, // true Parent === child.constructor, // true Parent=== Parent.prototype.constructor // true );حالا بیاید این چیزایی که یاد گرفتیم رو مقایسه کنیم با Class Inheritance تو جاوااسکریپت جدیدخب شبیه به بقیه زبان های برنامه نویسی تعریف کلاس و ارث‌بری ازش به شکل زیر قابل انجامهclass Parent{ constructor() { this.name = "Parent"; } speak(){ console.log(this.name+" speaks!"); } } class child extends Parent{ constructor(name) { super(); this.name = name ; } } var mohsen= new child("mohsen"); mohsen.speak(); // mohsen speaksاگر نکته ای داشتید خوشحال میشم به مطلب من اضافه کنیدو اینکه اگر توسعه دهنده جاوااسکریپت خوبی هستید کلی موقعیت شغلی هر روز برای شما اینجا هست و یک رویداد خفن هم بزودی برگزار میشه که اینجا می تونید اطلاعات بیشتر رو پیدا کنید استخدام