خواص (Properties)
property (خصوصیت) استانداردی در جاوااسکریپت، برای دسترسی به فیلدها با سطح دسترسی private در داخل یک کلاس میباشد. همانطور که در درس قبل اشاره شد، تعریف فیلدها در داخل کلاس به صورت public اشتباه است، چون کاربران میتوانند با ایجاد یک شیء از کلاس به آنها دسترسی داشته باشند و هر مقداری که دوست دارند به آنها اختصاص دهند. برای رفع این مشکل مفهوم property ارائه شد. هر property دارای دو بخش میباشد، یک بخش جهت مقدار دهی (بلوک set) و یک بخش برای دسترسی به مقدار (بلوک get) یک داده private میباشد. property ها باید به صورت public تعریف شوند تا در کلاسهای دیگر نیز قابل دسترسی میباشند. در مثال زیر نحوه تعریف و استفاده از property آمده است :
1: class Person 2: { 3: #name ; 4: #age ; 5: #height; 6: 7: get Name() 8: { 9: return this.#name; 10: } 11: set Name(value) 12: { 13: this.#name = value; 14: } 15: 16: get Age() 17: { 18: return this.#age; 19: } 20: set Age(value) 21: { 22: this.#age = value; 23: } 24: 25: get Height() 26: { 27: return this.#height; 28: } 29: set Height(value) 30: { 31: this.#height = value; 32: } 33: 34: constructor(name, age, height) 35: { 36: this.#name = name; 37: this.#age = age; 38: this.#height = height; 39: } 40: } 41: 42: var person1 = new Person("Jack", 21, 160); 43: var person2 = new Person("Mike", 23, 158); 44: 45: console.log(`Name : ${person1.Name}`); 46: console.log(`Age : ${person1.Age} years old`); 47: console.log(`Height: ${person1.Height} cm`); 48: 49: console.log("\n"); //Seperator 50: 51: console.log(`Name : ${person2.Name}`); 52: console.log(`Age : ${person2.Age} years old`); 53: console.log(`Height: ${person2.Height} cm`); 54: 55: console.log("\n"); //Seperator 56: 57: person1.Name = "Frank"; 58: person1.Age = 19; 59: person1.Height = 162; 60: 61: person2.Name = "Ronald"; 62: person2.Age = 25; 63: person2.Height = 174; 64: 65: console.log(`Name : ${person1.Name}`); 66: console.log(`Age : ${person1.Age} years old`); 67: console.log(`Height: ${person1.Height} cm`); 68: 69: console.log("\n"); //Seperator 70: 71: console.log(`Name : ${person2.Name}`); 72: console.log(`Age : ${person2.Age} years old`); 73: console.log(`Height: ${person2.Height} cm`);
Name : Jack Age : 21 years old Height: 160cm Name : Mike Age : 23 years old Height: 158cm Name : Frank Age : 19 years old Height: 162cm Name : Ronald Age : 25 years old Height: 174cm
در برنامه بالا نحوه استفاده از property آمده است. همانطور که مشاهده میکنید در این برنامه ما سه فیلد (خطوط 5-3) تعریف کردهایم (سه فیلد با سطح دسترسی private).
3: #name ; 4: #age ; 5: #height;
دسترسی به مقادیر این فیلدها فقط از طریق property های ارائه شده (خطوط 32-7) امکان پذیر است.
7: get Name() 8: { 9: return this.#name; 10: } 11: set Name(value) 12: { 13: this.#name = value; 14: } 15: 16: get Age() 17: { 18: return this.#age; 19: } 20: set Age(value) 21: { 22: this.#age = value; 23: } 24: 25: get Height() 26: { 27: return this.#height; 28: } 29: set Height(value) 30: { 31: this.#height = value; 32: }
به این نکته توجه کنید که طبق قرارداد، نام property ها همانند نام فیلدهای مربوطه میباشد با این تفاوت که حرف اول آنها بزرگ نوشته میشود. تاکید می کنیم که، شباهت نام property ها و فیلدها اجبار نیست و یک قرارداد میباشد.
به کلمه value در داخل بلوک set توجه کنید. Value همان مقداری است که از طریق property به فیلد اختصاص میدهیم. برای اختصاص یک مقدار به یک فیلد از طریق property کافیست که به صورت زیر عمل کنید :
Object.Property = Value;
این کار (قرار دادن یک مقدار بعد از علامت مساوی) به منزله فراخوانی بخش set است. و ما به برنامه میفهمانیم که میخواهیم از طریق بخش set یک فیلد را مقداردهی کنیم. Object شیء ایجاد شده از کلاس، Property نام پراپرتی و Value مقداری است که میخواهیم به فیلد اختصاص دهیم. برای دسترسی به یک خاصیت میتوانید از علامت دات (.) استفاده کنید. مثلاً برای اختصاص مقدار به سه فیلد age ،name و height از طریق property باید به صورت زیر عمل کنید :
57: person1.Name = "Frank"; 58: person1.Age = 19; 59: person1.Height = 162;
دستورات بالا بخش set مربوط به هر property را فراخوانی کرده و مقادیری به هر یک از فیلدها اختصاص میدهد. برای فراخوانی بخش get کافیست که نام شیء و سپس علامت نقطه و در آخر نام property را بنویسیم. با این کار به برنامه میفهمانیم که ما نیاز به مقدار فیلد داریم.
65: console.log(`Name : ${person1.Name}`); 66: console.log(`Age : ${person1.Age} years old`); 67: console.log(`Height: ${person1.Height} cm`);
استفاده از property ها کد نویسی را انعطاف پذیر میکند مخصوصاً اگر بخواهید یک اعتبارسنجی برای اختصاص یک مقدار به فیلدها یا استخراج یک مقدار از آنها ایجاد کنید. پس میتوان گفت که :
مثلاً در مثال زیر شما میتوانید یک محدودیت ایجاد کنید که فقط اعداد مثبت به فیلد age (سن) اختصاص داده شود. میتوانید با تغییر بخش set خاصیت Age این کار را انجام دهید:
get Age() { return this.#age; } set Age(value) { if(value > 0 && value < 100) { this.#age = value; } else { return 0; } }
حال اگر کاربر بخواهد یک مقدار منفی به فیلد age اختصاص دهد مقدار age صفر خواهد شد. همچنین میتوان یک property فقط خواندنی (read-only) ایجاد کرد. این property فاقد بخش set است. به عنوان مثال میتوان یک خاصیت Name فقط خواندنی مانند زیر ایجاد کرد :
get Age() { return this.#age; }
در این مورد اگر بخواهید یک مقدار جدید به فیلد name اختصاص دهید با خطا مواجه میشوید. یک property میتواند دارای دو فیلد باشد. به کد زیر توجه کنید :
#firstName; #lastName; get FullName() { return this.#firstName + " " + this.#lastName; }
همانطور که در مثال بالا مشاهده میکنید یک property فقط خواندنی تعریف کردهایم که مقدار برگشتی آن ترکیبی از دو فیلد firstName و lastName است که به وسیله فاصله از هم جدا شدهاند.