در زبان JavaScript و ورژن ECMAScript 5 نحوه تعریف کردن کلاس شبیه به آنچه که در زبان های دیگر از قبیل سی شارپ و یا جاوا وجود دارد امکان پذیر نیست. به عبارت دیگر، در این نسخه از JavaScript چیزی به نام کلاس وجود ندارد. بنابراین، می توان گفت که زبان JavaScript از این نظر شبیه به زبان سی شارپ و یا JavaScript از شی گرایی پشتیبانی نمی کند.
اما میتوانیم یک تابع را طوری تعریف کنیم که شبیه به یک کلاس عمل کند. مثالی که در قسمت زیر مشاهده می کنید نحوه تعریف کردن یک تابع شبیه به یک کلاس را در JavaScript نشان میدهد.
function
Person() {
this.firstName = "unknown";
this.lastName = "unknown";
}
var
person1 = new
Person();
person1.firstName = "Steve";
person1.lastName = "Jobs";
alert(person1.firstName + " "
+ person1.lastName);
var
person2 = new
Person();
person2.firstName = "Bill";
person2.lastName = "Gates";
alert(person2.firstName + " "
+ person2.lastName );
همانطور که در مثال بالا مشاهده می کنید ()Person یک تابع است که شامل متغیرهایی به نامهای firstName و lastName و age می باشد که با استفاده از کلمه کلیدی this تعریف شده اند. این متغیرها شبیه به property های کلاس رفتار خواهند کرد. همانطور که احتمالاً می دانید شما می توانید پس از تعریف کردن یک کلاس از آن یک object ایجاد کنید. برای انجام این کار نیز میتوانید از تابع مورد نظر با استفاده از کلمه کلیدی new یک object ایجاد کنید. بنابراین person1 یک object با استفاده از کلمه کلیدی new خواهد بود.
تا به اینجای کار دیدیم که Person هر چند که یک تابع است، شبیه به یک کلاس رفتار می کند و person1 و person2 هر دو object ها و یا instance هایی از این کلاس هستند. هر object مقادیر خاص خود را برای متغیرهای تعریف شده در تابع مورد نظر خواهد داشت که این موضوع حالت و یا state مربوط به object مورد نظر را تشکیل خواهد داد.
پس تا به اینجای کار دیدیم که چگونه میتوان از یک تابع برای ایجاد کردن یک کلاس در JavaScript استفاده نمود.
می توان function هایی را در قالب متغیر به یک کلاس در JavaScript اضافه کرد. این موضوع در کد زیر نشان داده شده است.
function
Person() {
this.firstName = "unknown";
this.lastName = "unknown";
this.getFullName = function(){
return
this.firstName + " "
+ this.lastName;
}
};
var
person1 = new
Person();
person1.firstName = "Steve";
person1.lastName = "Jobs";
alert(person1.getFullName());
var
person2 = new
Person();
person2.firstName = "Bill";
person2.lastName = "Gates";
alert(person2.getFullName());
همانطور که در مثال بالا مشاهده می کنید تابع Person شامل یک تابع دیگر به نام getFullName میباشد. این getFullName شبیه یک متد برای کلاس Person ایفای نقش میکند و میتواند با استفاده از نقطه و شبیه به person1.getFullName صدا زده بشود.
در دیگر زبان های برنامه نویسی از قبیل Java و سی شارپ یک کلاس می تواند یک یا چند تابع سازنده داشته باشد. در JavaScript یک تابع میتواند یک و یا چندین پارامتر داشته باشد. بنابراین، یک تابع می تواند یک یا چند پارامتر ورودی را به عنوان تابع سازنده دریافت کند تا بتوانید در زمان ایجاد کردن یک object با استفاده از کلمه کلیدی new مقادیری را در آن در نظر بگیرید. این موضوع در کد زیر نشان داده شده است.
function
Person(FirstName, LastName, Age) {
this.firstName = FirstName || "unknown";
this.lastName = LastName || "unknown";
this.age = Age || 25;
this.getFullName = function
() {
return
this.firstName + " "
+ this.lastName;
}
};
var
person1 = new
Person("James","Bond",50);
alert(person1.getFullName());
var
person2 = new
Person("Tom","Paul");
alert(person2.getFullName());
همانطور که در مثال بالا مشاهده می کنید تابع Person شامل سه پارامتر ورودی به نامهای FirstName و LastName و Age می باشد. این پارامترهای ورودی برای تنظیم کردن مقادیر مربوط به property هایی که با همین نام تعریف شدهاند استفاده می شود.
لطفاً دقت کنید که پارامترهای انتساب داده شده به یک property اگر مقدار آن پارامتر در زمان ایجاد شدن یک object با استفاده از کلمه کلیدی new لحاظ نشود، مقدار undefined خواهد داشت.
Object.defineProperty به عنوان یک متد میتواند یک property را با getter و setter تعریف کند. کدی که در قسمت زیر مشاهده می کنید نحوه ایجاد کردن یک property با getter و setter را نشان میدهد.
function
Person() {
var
_firstName = "unknown";
Object.defineProperties(this, {
"FirstName": {
get: function
() {
return
_firstName;
},
set: function
(value) {
_firstName = value;
}
}
});
};
var
person1 = new
Person();
person1.FirstName = "Steve";
alert(person1.FirstName );
var
person2 = new
Person();
person2.FirstName = "Bill";
alert(person2.FirstName );
در مثال بالا تابع function یک property به نام FirstName را با استفاده از Object.defineProperties تعریف می کند. اولین آرگومان this می باشد که به پروپرتی FirstName با صدا زدن object اصطلاحاً bind می شود.
دومین آرگومان یک object است که شامل لیستی از property هایی می باشد که می بایست ایجاد بشود. ما پروپرتی FirstName را با توابع get و set تعریف کردهایم. بنابراین، میتوانیم از این property با استفاده از نقطه شبیه به کدی که در قسمت بالا دیدید استفاده کنیم.
برای تعریف کردن property ها به صورت فقط خواندنی و یا read-only قسمت set مربوط به آنها را تعریف نمی کنیم. این موضوع در کد زیر نشان داده شده است.
function
Person(firstName) {
var
_firstName = firstName || "unknown";
Object.defineProperties(this, {
"FirstName": {
get: function
() {
return
_firstName;
}
}
});
};
var
person1 = new
Person("Steve");
//person1.FirstName = "Steve"; -- will not work
alert(person1.FirstName );
var
person2 = new
Person("Bill");
//person2.FirstName = "Bill"; -- will not work
alert(person2.FirstName );
می توانیم بیش از یک property را با استفاده از متد defineProperties شبیه به چیزی که در کد زیر مشاهده می کنید تعریف کنیم.
function
Person(firstName, lastName, age) {
var
_firstName = firstName || "unknown";
var
_lastName = lastName || "unknown";
var
_age = age || 25;
Object.defineProperties(this, {
"FirstName": {
get: function
() { return
_firstName },
set: function
(value) { _firstName = value }
},
"LastName": {
get: function
() { return
_lastName },
set: function
(value) { _lastName = value }
},
"Age": {
get: function
() { return
_age },
set: function
(value) { _age = value }
}
});
this.getFullName = function
() {
return
this.FirstName + " "
+ this.LastName;
}
};
var
person1 = new
Person();
person1.FirstName = "John";
person1.LastName = "Bond";
alert(person1.getFullName());
منبع: وبسایت پرووید