از سال 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
اگر نکته ای داشتید خوشحال میشم به مطلب من اضافه کنید
و اینکه اگر توسعه دهنده جاوااسکریپت خوبی هستید کلی موقعیت شغلی هر روز برای شما اینجا هست و یک رویداد خفن هم بزودی برگزار میشه که اینجا می تونید اطلاعات بیشتر رو پیدا کنید
استخدام
مطلبی دیگر از این انتشارات
معرفی کتابخانه XOBJ.JS : کار با اشیا، بدون درد و خونریزی!
مطلبی دیگر از این انتشارات
برنامهنویسی Front-end یا سمت کاربر رو از کجا شروع کنیم؟
مطلبی دیگر از این انتشارات
کوتاه تر کد بنویسیم (قسمت سوم)