Prototype و متدهای ES5 در اشیاء جاوا اسکریپتی

26 اسفند 1397
Advanced-Javascript-prototypes-es5-methods

با سلام و عرض ادب خدمت شما همراهان روکسو، در این قسمت با مفهومی آشنا می شویم که شاید از دید اکثر برنامه نویسان مبتدی و بعضا حرفه ای دور مانده باشد و آن مبحث prototype ها است. سپس به معرفی برخی از متدهای جدید در ECMAScript 5 می پردازیم چرا که بسیار به درد بخور و مفید هستند.

prototype چیست؟

prototype در لغت به معنی «نمونه ی اولیه» است. در واقع تمام اشیاء جاوا اسکریپتی متدها و خصوصیات خود را از یک prototype به ارث می برند. این prototype ها همانطور که از نامشان مشخص است نمونه ی اولیه و طرح کلی برای دسته ای از اشیاء هستند.

اگر یادتان باشد در جلسه ی قبل در رابطه با object constructor ها صحبت کردیم و مثال زیر را برایتان آوردیم:

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Objects</h2>

<p id="demo"></p>

<script>
function Person(first, last, age, eye) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eye;
}

var myFather = new Person("John", "Doe", 50, "blue");
var myMother = new Person("Sally", "Rally", 48, "green");

document.getElementById("demo").innerHTML =
"My father is " + myFather.age + ". My mother is " + myMother.age; 
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

اگر یادتان باشد به شما گفتیم که نمی توانیم property (خصوصیت) های دلخواه خود را به constructor اضافه کنیم و کد زیر غلط از آب در می آمد:

Person.nationality = "English";

بلکه باید آن را به شکل دستی به خودِ تابعِ constructor اضافه می کردیم:

function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
  this.nationality = "English";
}

این مثال ها را در ذهن داشته باشید تا در ادامه از آن ها استفاده کنیم.

ارث بری از prototype

همانطور که گفتیم تمام اشیاء جاوا اسکریپتی متدها و خصوصیات خود را از یک prototype به ارث می برند اما مشخص نکردیم از کدام prototype:

  • Date ها از Date.prototype ارث بری می کنند.
  • Array ها از  Array.prototype ارث بری می کنند.
  • Person ها (همان مثال خودمان) از  Person.prototype ارث بری می کنند.

بنابراین قانون کلی به این شکل است که یک شیء از Object.prototype ارث بری دارد.

مثال های استفاده از prototype

حالا که در مورد prototype اطلاعات کسب کردیم باید بدانید می توانیم از طریق آن به تابعِ constructor دسترسی داشته باشیم.

در این مثال می خواهیم با استفاده از prototype  یک خصوصیت (property) جدید ایجاد کنیم که در شیء ما وجود نداشته است.

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Objects</h2>

<p id="demo"></p>

<script>
function Person(first, last, age, eye) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eye;
}

Person.prototype.nationality = "English";

var myFather = new Person("John", "Doe", 50, "blue");
document.getElementById("demo").innerHTML =
"The nationality of my father is " + myFather.nationality; 
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

همانطور که مشخص است به راحتی خصوصیت nationality را اضافه کردیم.

برای اضافه کردن متدها نیز به همین شیوه عمل می کنیم:

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Objects</h2>

<p id="demo"></p>

<script>
function Person(first, last, age, eye) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eye;
}

Person.prototype.name = function() {
  return this.firstName + " " + this.lastName
};

var myFather = new Person("John", "Doe", 50, "blue");
document.getElementById("demo").innerHTML =
"My father is " + myFather.name(); 
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

هشدار: تنها prototype های خودتان را تغییر دهید! به هیچ عنوان به prototype های پیش فرض جاوا اسکریپت و اشیاء استاندارد آن دست نزنید چرا که تمام برنامه بهم خواهد ریخت.

متدهای جدید در ECMAScript 5

در ECMAScript 5 متدهای جدیدی برای کار با اشیاء معرفی شدند. ما میخواهیم با مهم ترینشان آشنا شویم:

// اضافه کردن و یا تغییر دادن یک خصوصیت از یک شیء
Object.defineProperty(object, property, descriptor)

// اضافه کردن و یا تغییر دادن چندین خصوصیت
Object.defineProperties(object, descriptors)

// دسترسی پیدا کردن به خصوصیت ها
Object.getOwnPropertyDescriptor(object, property)

// برگرداندن تمام خصوصت ها به شکل یک آرایه
Object.getOwnPropertyNames(object)

// برگرداندن خصوصیت های عددی در قالب یک آرایه
Object.keys(object)

// prototype دسترسی پیدا کردن به
Object.getPrototypeOf(object)

// سلب اجازه ی اضافه کردن خصوصیات به یک شیء
Object.preventExtensions(object)
// را بر میگرداند true اگر اجازه داشته باشیم که خصوصیت ها را به شیء ای اضافه کنیم مقدار
Object.isExtensible(object)

// اجازه ی تغییر خود خصوصیات (و نه مقدار ها) را سلب می کند
Object.seal(object)
// را بر میگرداند true اگر اجازه نداشته باشیم که خصوصیت ها را به شیء ای اضافه کنیم مقدار
Object.isSealed(object)

// از ایجاد هر تغییری در شیء جلوگیری می کند
Object.freeze(object)
// را بر میگرداند true اگر اجازه نداشته باشیم که تغییراتی در شیء ایجاد کنیم مقدار
Object.isFrozen(object)

در کدهای بالا توضیحات را به صورت مثال آورده ام که می توانید مطالعه کنید اما چند مورد از کدهای بالا را در یک مثال بررسی می کنیم تا با نحوه ی کارشان آشنا شوید.

تغییر مقدارِ یک خصوصیت

ساختار کلی کد به این شکل است:

Object.defineProperty(object, property, {value : value})

property به معنی خصوصیت و value به معنی مقدار (یعنی مقدارِ آن خصوصیت) است. به طور مثال:

var person = {
  firstName: "John",
  lastName : "Doe",
  language : "EN" 
};

// تغییر دادن یک خصوصیت
Object.defineProperty(person, "language", {value : "NO"});

تغییر metadata ها

تغییر متادیتاها به شکل زیر است:

writable : true      // مقدار خصوصیت ها قابل تغییر است
enumerable : true    // خصوصیت ها قابل شمارش اند
configurable : true  // خصوصیت ها قابل پیکربندی و تنظیم شدن اند.

برای هر کدام مقدار False هم داریم که برعکس توضیحات بالا خواهد بود.

دریافت تمام خصوصیت ها

برای دریافت تمام خصوصیت های یک شیء می توانیم به این شکل عمل کنیم:

var person = {
  firstName: "John",
  lastName : "Doe"
  language : "EN" 
};

Object.defineProperty(person, "language", {enumerable:false});
Object.getOwnPropertyNames(person);  // یک آرایه از تمام خصوصیات برمیگرداند

تعریف Getter و Setter

در قسمت های قبلی با مبحث Getter و Setter آشنا شدیم اما باید بدانید می توانید با ()Object.defineProperty نیز آن ها را تعریف کنید:

// ساخت یک شیء
var person = {firstName:"John", lastName:"Doe"};

// تعریف کردن یک getter
Object.defineProperty(person, "fullName", {
  get : function () {return this.firstName + " " + this.lastName;}
});

امیدوارم از این قسمت لذت برده باشید. این قسمت، قسمت پایانی اشیاء بود و در قسمت بعد به سراغ توابع جاوا اسکریپت می رویم. پس از بحث در مورد توابع جاوا اسکریپت (به صورت پیشرفته) مستقیما به سراغ دسترسی به DOM و BOM خواهیم رفت. اصل استفاده ی جاوا اسکریپت در این زمینه است بنابراین پیشنهاد می کنم آن را از دست ندهید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری جاوا اسکریپت پیشرفته توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

امیر
29 آذر 1399
بسیار خوب مفهوم اشیا توضیح داده شده جند وقته درگیر اشیا بودم اینجا کامل متوجه شدم سپاس از روکسو و سپاس ویژه از آقای زوارمی

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.