از سال 81 با flash و actionscript برنامه های مالتی مدیا میساختم ، از 84 طراحی وب ، از 89 php ، از 92 اندروید و جاوا ، از 96 تمرکزم روی جاوااسکریپت هست
داستان 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
اگر نکته ای داشتید خوشحال میشم به مطلب من اضافه کنید
و اینکه اگر توسعه دهنده جاوااسکریپت خوبی هستید کلی موقعیت شغلی هر روز برای شما اینجا هست و یک رویداد خفن هم بزودی برگزار میشه که اینجا می تونید اطلاعات بیشتر رو پیدا کنید
استخدام
مطلبی دیگر از این انتشارات
افزایش سرعت بارگذاری وب سایت (قسمت اول)
مطلبی دیگر از این انتشارات
دلایلم برای انتخاب جاوااسکریپت
مطلبی دیگر از این انتشارات
آشنایی با styled-components