تعریف ویژگی ها (Properties) در جاوا اسکریپت

۱۳۸۷/۰۹/۰۸ ۲۲:۲۱ Salar Khalilzadeh https://plus.google.com/105397214522932500988 منتشر شده در تاریخ : ۱۳۸۷/۰۹/۰۸ دسته بندی : ، ، ، 6

یکی از امکانات نسخه های جدید JavaScript پشتیبانی از ویژگی ها (Property) هست. اگر با سایر زبان های برنامه نویسی آشنایی داشته باشید، مطمئنن می دانید که ویزگی ها یکی از بخش های جدایی ناپذیر زبانهای برنامه نویسی OOP هستند.

ویژگی ها این امکان را فراهم می کنند که بر روی مقادیر متغیرهای خود کنترل داشته باشید و حق دسترسی برای آنها جهت ویرایش تعیین کنید. همچنین می توان داده های وارده را فیلتر کرده تا فقط محدوده و داده های مورد نظر اعمال شوند.

با این مقدمه می خواهم چند روش تعریف ویژگی ها در جاوا اسکریپت مطرح کنم.

تعریف اول:

جاوا اسکریپت زبان بسیار ساده ای است. ابجکت ها (یا اشیا) در جاوا اسکریپت چیزی بیش از مجموعه ای از کلید ها و مقادیر نیستند. به این معنی که برای دسترسی به عضوی از یک شیئ می توانید همانند یک آرایه با آن رفتار کنید.

برای مثال برای افزودن یک عضو به یک شیئ به مثال زیر توجه کنید:
var thing = new Object();
thing[ “prop1” ] = “Hello”;

در این مثال ما عضو جدیدی به نام prop1 را به thing اضافه کردیم. مقدار prop1 برابر Hello خواهد بود. روش دیگری هم برای افزودن عضو به شیئ مورد وجود دارد. به مثال زیر توجه کنید:
var thing = new Object();
thing.prop1 = “Hello”;

روش دیگر برای معرفی اشیا استفاده از لیتراتهای ابچکت هست که نتیجه ای دقیقا مانند دو مثال قبلی دارد:
var thing = {prop1 : “Hello”};

استفاده از مقدار prop1 بسیار ساده است می توان همانند یک آرایه یا یک ویژگی از آن استفاده کرد:
var thing = new Object();
thing.prop1 = “Hello”;
alert( thing[“prop1”] );
thing.prop1 = “Hello Again!”;
alert( thing.prop1 );

روش دوم:

روشی که در بالا توضیح دادم خیلی ساده و کاربردی است ولی تنها محدودیتی که دارد این است که امکان کنترل بر داده هایی که قبول می کند و یا مقداری که باید برگرداند وجود ندارد.

برای رفع این مشکل شرکت Mozilla راه حلی را ارائه کرده است که به مرور سایر مرورگر ها نیز از آن پشتیبانی می کنند.

این روش چیزی جز کلمات کلیدی get و set نیست.
var thing =  {
_price: 0,
get price() { return this._price; },
set price(value)
{
if (value < 0)
throw "price must be greater than zero";
this._price = value;
}
};

در این مثال شیئ با نام thing تعریف شده است. این شیئ دارای یک متغیر با نام price_ و ویژگی price هست که با استفاده از یک متد get و یک متد set تعریف شده است.

به طور ساده تر زمانی که می خواهید مقداری را از ویزگی price بخوانید تابع معرفی شده در مقابل get فراخوانی خواهد شد و همچنین، هنگام مقدار دهی به price تابع معرفی شده در مقابل set فراخوانی خواهد شد.

همانطور که می بینید ویزگی price در هنگام عمل set مقدار ورودی را بررسی می کند و اگر کوچکتر از صفر باشد خطایی را تولید خواهد کرد.

نمونه استفاده از کد بالا:
// مقدار دهی
thing.price = 5;
// نمایش مقدار
alert( thing.price );
// مقدار نامعتبر و تولید خطا
thing.price = -10;

متاسفانه از این روش مرورگر های کمی پشتیبانی می کنند و در حال حاظر مرورگرهای Firefox و Safari 3 و Opera 9.5 از آن پشتیبانی می کنند.

روش سوم:

این روش را مرورگر Firefox برای استفاده در خودش طراحی کرده و در سایر مرورگرها کار نخواهد کرد. روش بسیار جالبی است و ساده تر از روش قبلی می باشد.
var thing =
{
_price: 0
};
thing.__defineGetter__("price", function(){ return this._price; });
thing.__defineSetter__("price", function(value)
{
if (value < 0)
throw "price must be greater than 0";
this._price = value;
}
);

در این مثال ابتدا شیئ thingتعرفی می شود. سپس با استفاده از تابع __defineGetter__ متد get با برای ویژگی price تعریف می شود. این تابع دو ورودی دارد که اولی نام ویژگی مورد نظر است و دومی رفرنسی به تابع مورد نظر برای get. البته در این مثال تابع در همان جا تعریف شده است.

تابع __defineSetter__ همانند __defineGetter__ عمل می کند و فقط برای اضافه کردن تعریف set به ویژگی مورد نظر مورد استفاده است. در این مثال تابع مربوط به set در همان خط تعریف شده و مقدار ورودی را برای مقادیر کمتر از صفر کنترل می کند.

همانند مثال قبلی این مثال نیز کار خواهد کرد:
// مقدار دهی
thing.price = 5;
// نمایش مقدار
alert( thing.price );
// مقدار نامعتبر و تولید خطا
thing.price = -10;

روش چهارم:

در این روشی که می خوام معرفی کنم، واقعا ویژگی ها را پیاده سازی نمی کند ولی مانند یک ویژگی عمل می کنه و می تونه در کار شما مفید واقع بشه. در این روش در حقیقت ما دو تابع جداگانه برای خواندن و نوشتن در متغیر تعریف می کنیم و کارهای مورد نظر را در داخل آنها انجام می دهیم.
function thing()
{
var _price = 0;
this.getPrice = function(){
return _price;
};
this.setPrice = function(val){
if (val < 0)
throw "price must be greater than 0";
_price = val;
};
}

در این مثال شیئ thing به عنوان یک تابع تعریف شده است که می توان از روی متغیر و اشیا دیگری هم ساخت. در داخل این تابع دو تابع getPrice برای خواندن و setPrice برای نوشتن در متغیر _price تعریف شده است.
// ایجاد نمونه جدید از تابع تعریف شده
var product= new thing();
// دسترسی متقیم به متغیر داخلی
alert(product._price);
//مقدار دهی با استفاده از تابع
product.setPrice(2);
// دسترسی به مقدار با استفاده از تابع مربوطه
alert( product.getPrice() );
// مقدار با یک مقدار نامعتبر و دریافت خطا
product.setPrice( -4 );

با این اوصاف مشاهده می کنید که javascript روز به روز قوی تر می شود، مخصوصا که Web 2 بسیار به javascript وابسته هستند.

موفق باشید

منابع:

http://weblogs.asp.net/stephenwalther/archive/2008/02/29/creating-javascript-properties-in-asp-net-ajax.aspx
http://ejohn.org/blog/javascript-getters-and-setters/
http://ajaxian.com/archives/getters-and-setters-in-javascript

 

6 بازخورد برای “تعریف ویژگی ها (Properties) در جاوا اسکریپت”

  1. ممنون, مطلب جالب و کاربردی ای بود

    پاسخحذف
  2. این روش از نظر encapsulation مشکل داره
    نباید به متغیر داخلی ، دسترسی مستقیم داشت و باید private باشد.
    عملآ هنوز هم قادر به مقدار دهی اشتباه هستیم.
    جالب اینجاس که قبل از مقدار دهی اشتباه این روش کار میکند
    یعنی اگر مقدار thing._price را با alert فراخوانی کنیم مقدار undefined میدهد یعنی دسترسی به price نداریم
    حال اگر thing._price=2 را انجام دهیم و دوباره مقدار thing._price را با alert فراخوانی کنیم ، مقدار 2 را میدهد ، این یعنی price حالت private بودن خود را از دست میدهد

    در هر صورت ممنون از لطفتون برای این پست
    قسمت آخر خط 01 که code نوشتید var thing=new thing باید به صورت
    var product=new thing باشد تا باقی کد صحیح باشد چون مقدار product تعریف نشده

    :) منبع

    پاسخحذف
  3. کاملآ درسته :) کلی چیز ازتون یاد گرفتیم ، ممنون

    پاسخحذف