درک پروتوتایپ (prototype) در جاوااسکریپت به زبانی ساده

درک پروتوتایپ (prototype) در جاوااسکریپت به زبانی ساده
Prototype یک مبحث بنیادی در برنامه نویسی جاوااسکریپته که هر برنامه نویس جاوااسکریپتی باید روی این موضوع تسلط داشته باشه و بتونه به راحتی مفهومش رو درک کنه که ما در این مقاله قصد داریم در مورد این موضوع به طور کامل صحبت کنیم.
دارالترجمه رسمی
دارالترجمه رسمی پارسیس شامل خدمات ترجمه رسمی و تخصصی در بیش از 60 زبان زنده دنیا
جای بروشور دیواری
خرید جای بروشور دیواری و رومیزی
افزونه های سئو وردپرس
بهترین افزونه های سئو وردپرس به صورت کاملا فارسی
تعمیر لوازم خانگی
تعمیر جاروبرقی، مایکروفر، بخارشوی، ظرفشویی، لباسشویی، سولاردام، کولرگازی
خودتان را اینجا معرفی کنید

برای درک موضوع Prototype ابتدا شما باید مفهوم Object رو درک کنید و سپس به ادامه موضوع بپردازید، پس به شما پیشنهاد میکنم قبل از ادامه موضوع این مقاله رو مطالع نمائید : "آبجکت های جاوااسکریپت و جزئیات آن‌ها!"
هرچند درک موضوع Prototype به آسانی درک موضوع variable در توابع هست .

هر Object  جاوااسکریپت یک prototype دارد و خود prototypeها نیز Object هستند!
تمام Objectهای جاوااسکریپت ویژگی‌ها و متدهای خود را از prototypeها به ارث می‌برند!

برای درک این دوجمله‌ی بالا لازم است ریزتر به مسائل دقت کنیم ، در مبحث " توابع و روش های فراخوانی آن ها در جاوااسکریپت " که یکی از جذابترین بخش های تابع هست اگر یادتون باشه یک ساختار رو تعریف میکردیم و در بخش های مختلف برنامه میتونستیم از اون تابع برای ایجاد و توسعه استفاده کنیم و مقداری رو فراخوانی میکردیم و با استفاده از تابع سازنده، مقدار نهایی برای ما بازگشت داده میشد. در اینجا هم هدف از prototype همین موضوع برای Objectها می باشد و شباهت زیادی به هم دارند.

تمام آبجکت‌های جاوااسکریپت (Date, Array, RegExp, Function, ....) از Object.Property ارث‌بری میکنند.

راه استاندارد برای ساخت یک object prototype این است که از تابع آبجکت سازنده(object constructor function) استفاده کنیم.
function person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
}
شما با کمک تابع سازنده، میتونید با کلمه کلیدی new  آبجکت‌های جدید رو شبیه prototype بسازید.
var myFather = new person("John", "Doe", 50, "blue");
var myMother = new person("Sally", "Rally", 48, "green");
enlightenedتابع سازنده یک prototype برای آبجکت person  می‌باشد.

تا به اینجا ما تقریبا موضوع رو تا حدود زیادی می‌دونستیم (با توجه به مقاله های قبل) و مفهوم اصلی prototype رو میشه گفت تا آخر مقاله کامل درک می‌کنید :)

برای افزودن یک ویژگی به آبجکت ما به راحتی می‌تونیم به صورت زیر عمل کنیم :
myFather.nationality = "English";
ولی نکته ای که مهم است اینه که ما این ویژگی رو به آبجکت myFather اضافه کردیم و آبجکت myMother هیچ تغییری نکرد.

برای افزودن یک متد به آبجکت هم به صورت زیر می‌تونیم عمل کنیم :
myFather.name = function () {
    return this.firstName + " " + this.lastName;
};
و بازم تاکید میکنم که این متد رو ما فقط به آبجکت myFather اضافه کردیم و آبجکت myMother هیچ تغییری نکرد.

حالا ما یک ویژگی رو به prototype اضافه می‌کنیم :

enlightenedبه سبک فوق نمی‌تونیم یک متد یا ویژگی رو به prototype اضافه کنیم چونکه prototype  یک آبجکت موجود نیست که مقداری بهش اضافه بشه و prototype یک سازنده محسوب میشه!
person.nationality = "English"; // Undefined
برای اضافه کردن ویژگی جدید به protottype به صورت زیر عمل میکنیم :
function person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
    this.nationality = "English"
}
enlightenedویژگی های prototype می‌تونند مقداری رو به صورت پیشفرض داشته باشند.

و برای افزودن متد به prototype می‌تونیم به صورت زیر عمل کنیم :
function person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
    this.name = function() {return this.firstName + " " + this.lastName;};
}
ولی اصل مطلب اینه که ما میتونیم به prototypeها به صورت خیلی ساده تر ویژگی و متدی را به صورت خارجی اضافه کنیم، به این صورت :
person.prototype.nationality = "English";
person.prototype.name = function() {
    return this.firstName + " " + this.lastName;
};
enlightenedدقت کنید که فقط prototypeهایی که خودتون می‌سازید رو تغییر دهید و به هیچ عنوان prototypeهای استاندارد جاوااسکریپت رو تغییر ندهید.

بابررسی مثال زیر می‌تونیم مفاهیم رو بهتر متوجه شویم :
function PrintStuff(myDocuments) {
​   this.documents = myDocuments;
}
​
​// متد جدیدی رو اضافه کردیم
PrintStuff.prototype.print = function () {
   console.log(this.documents);
}
​
​// آبجکت جدیدی رو ساختیم که مقداری رو به تابع سازنده ارسال میکنه
​var newObj = new PrintStuff("MajidOline.com");
​
​//همانطور که می‌بینید آبجکت جدید همه ویژگی‌ها و متدها رو به ارث برده ​
newObj.print (); //MajidOnline.com
و مثال آخر مثالی پیچیده تر و کاربردی‌تر :
function Plant() {
​  this.country = "Iran";
​  this.isOrganic = true;
}
​
​// (plant)افزودن متد جدید به تابع فوق
Plant.prototype.showNameAndColor = function() {
   console.log("I am a " + this.name + " and my color is " + this.color);
}
​
​// افزودن متد جدید به تابع فوق(plant)
Plant.prototype.amIOrganic = function() {
     ​if(this.isOrganic)  // true
        console.log("I am organic!");
}
​
​function Fruit(fruitName, fruitColor) {
   ​this.name = fruitName;
​   this.color = fruitColor;
}
​
​// ست کردن پروتوتایپ "فروت" به تابع سازنده "پلانت" وبه ارث‌بردن تمام ویژگی ها و متدهای اون 
// Set the Fruit's prototype to Plant's constructor

Fruit.prototype = new Plant();
​
​// ساخت آبجکت جدید از تابع سازند "Fruit"
​var aBanana = new Fruit("Banana", "Yellow");
​
console.log(aBanana.name); // Banana​
​
​// در این قسمت از متدی استفاده میشود که از پروتوتایپ قبلی به ارث برده 
console.log(aBanana.showNameAndColor()); // I am a Banana and my color is yellow.

امیدوارم مفید بوده باشه.

شاد باشید wink

من میکائیل اندیشه هستم که از سال ۲۰۱۱ وارد حوزه برنامه نویسی و طراحی وب شدم، ابتدا با زبان‌ c++ در رشته تحصیلیم ( مهندسی فناوری اطلاعات ) آشنا شدم و پس از آن وارد طراحی وب سمت کلاینت ( Front-End ) شدم و پس از چند سال کار و تجربه در این حوزه از اواسط ۲۰۱۷ وارد برنامه نویسی و سمت بک اند شدم و با زبان php کار میکنم. به زبان‌های php و javascript علاقه زیادی دارم و سعی میکنم در این دو بخش بیشتر یاد بگیرم.

نظرات و سوالات کاربران

ارسال پاسخ NaN
NaN
پنج شنبه ۳۱ مرداد ۱۳۹۸ ۱۰:۵۳
سلام با تشکر بسیار خوب توضیح دادید فقط مثال آخرتون توی خط اخرش به جای اینکه کل متد توی کنسول لاگ کنید بهتر که فقط متد رو فراخوانی کنید چون از قبل دستور console.logرو بهش دادین.
ارسال پاسخ Dada
Dada
سه شنبه ۳۰ بهمن ۱۳۹۷ ۲۰:۵۷
تمام آبجکت‌های جاوااسکریپت (Date, Array, RegExp, Function, ....) از Object.Property ارث‌بری میکنند.
correct:
Object.Prototype
ارسال پاسخ null
null
چهارشنبه ۱۲ دی ۱۳۹۷ ۱۲:۲۹
من برنامه نویسم ولی اینجور که شما نوشتید من هیچی دستمو نگرفت خواهشا اول مطلب رو خودتون درک کنید بعد آموزش بدید :)
ارسال پاسخ rreza
rreza
شنبه ۰۲ تیر ۱۳۹۷ ۲۰:۳۶
اقا من بازم متوجه نشدم
کلا متوجه نشدم
خب این چه کاریه یعنی چی this.firstName = first;
ارسال پاسخ داود
داود
دوشنبه ۲۲ آبان ۱۳۹۶ ۱۵:۳۶
سلام،من فهمیدم و جالب بود اما کاش جداگانه (یعنی در حد یه پاراگرف در همین صفحه)توضیحی در مورد ست کردن میدادید،اونطور که من متوجه شدم تابعی که جلوش ".prototype"باشه و بعدش یک سازنده بیاریم،تمام خصوصیات اون سازنده به این تابعی که جلوش از ".prototype" استفاده کردیم منتقل میشه(به ارث برده میشه) اما سوال من اینه در مورد ساخت ابجکت هم همین اتفاق میفته یا فرق داره؟
ارسال پاسخ محمد
محمد
شنبه ۱۱ شهریور ۱۳۹۶ ۰۰:۰۳
دمت گرم کلی تو رفرنسای خارجی سر این مونده بودم
ارسال پاسخ امین
امین
شنبه ۰۸ آبان ۱۳۹۵ ۲۲:۱۶
سلام. ببخشید یه سوال داشتم.
تو es6 که برای ساختن کلاس از کلمه کلیدی class استفاده میکنیم. دو تا کلاس مختلف تعریف می کنیم. در کلاس دوم ما یک ویژگی داریم که آرایه‌ای از شی‌های کلاس اول است. حالا اگه بخوایم روی این ویژگی عملیاتی انجام بدیم باید متد کلاس اول را تو کلاس دوم فراخوانی کنیم.
به طور خلاصه چجوری میشه تو یه کلاس از متد یه کلاس دیگه استفاده کرد بدون ارث بری؟
ارسال پاسخ آرش
آرش
پنج شنبه ۳۰ اردیبهشت ۱۳۹۵ ۰۱:۲۶
حرف نداشت
ارسال پاسخ میکائیل
میکائیل
شنبه ۲۶ دی ۱۳۹۴ ۱۲:۰۷
در پاسخ به دیدگاه دنی ارسال شده در پنج شنبه ۱۷ دی ۱۳۹۴ ۲۲:۴۵

عالی بود

مرسی خوشحالم مفید بوده براتون :)
ارسال پاسخ میکائیل
میکائیل
شنبه ۲۶ دی ۱۳۹۴ ۱۲:۰۷
در پاسخ به دیدگاه محمد نبی زاده ارسال شده در شنبه ۱۹ دی ۱۳۹۴ ۱۱:۵۳

خیلی خوب بود

خوشحالم مفید بوده براتون :)
ارسال پاسخ محمد نبی زاده
محمد نبی زاده
شنبه ۱۹ دی ۱۳۹۴ ۱۱:۵۳

خیلی خوب بود

ارسال پاسخ دنی
دنی
پنج شنبه ۱۷ دی ۱۳۹۴ ۲۲:۴۵

عالی بود