سلام دوستان! توی این قسمت می‌خوایم با یک ویژگی کاربردی از آبجکت‌های جاوااسکریپت آشنا بشیم: Accessor Property

توی این قسمت یاد می‌گیریم که:

 

مشکل کجاست؟ 🤔

همونطور که می‌دونیم یک آبجکت جاوااسکریپتی، شامل پراپرتی‌هایی بصورت Key و Value هست. پراپرتی‌ها، ویژگی‌های یک آبجکت رو شرح میدن. برای مثال آبجکت person رو در نظر بگیرید:

const person = {
  first_name: 'John',
  last_name:  'Doe',
}

کلیدهای first_name ،last_name و مقدار اونها، ویژگی‌ها و مشخصات آبجکت person رو شرح میدن. ما بصورت زیر (خط ۶) می‌تونیم به این مشخصات دسترسی داشته باشیم:

const person = {
  first_name: 'John',
  last_name:  'Doe',
};

const full_name = person.first_name + ' ' + person.last_name;

alert(full_name); // John Doe

ما توی مثال بالا قصد داشتیم اسم کامل (نام و نام‌خانوادگی) شخص رو چاپ کنیم. پس هر جایی از برنامه که نیاز داریم اسم کامل شخص رو چاپ کنیم باید مثل خط ۶ کد بالا، first_name و last_name رو به هم بچسبونیم که انجام این کار علاوه بر اینکه زمان‌بر هست، باعث به وجود اومدن کدهای تکراری توی برنامه میشه. ما با یک راه‌حل بهتر می‌تونیم این مسئله رو حل کنیم که اون هم استفاده از Accessor Property هاست 👌

 

Accessor Property چیه؟ 🤔

به تابعی گفته میشه که به یک شکل خاص توی آبجکت تعریف میشه و زمانی که می‌خوایم از بیرون از آبجکت، مقدار یک پراپرتی رو بخونیم و یا مقدار اون رو عوض کنیم، اجرا میشه تا بتونیم مقدار پراپرتی رو به بصورت دلخواه نمایش بدیم و یا ذخیره کنیم.

ما دو نوع Accessor Property داریم: Getter و Setter

 

پراپرتی‌های Getter

پراپرتی‌ای هست که به صورت یک تابع توی آبجکت تعریف میشه. این تابع، زمانی که می‌خوایم از بیرون از آبجکت، مقدار این پراپرتی رو بخونیم، اجرا میشه تا خروجی شخصی‌سازی شده‌ای بهمون بده.

برای نوشتن این نوع پراپرتی، کافیه قبل از تعریف تابع، از کلمه کلیدی get بصورت خط ۵ کد زیر استفاده کنیم:

const person = {
  first_name: 'John',
  last_name:  'Doe',
  
  <<get>> full_name() {
    return this.first_name + ' ' + this.last_name;
  }
};

alert(person.full_name); // John Doe

اینجا توی خط ۵ یک متد Getter به اسم full_name تعریف کردیم که توی اون داریم مقدار دلخواهی رو به خروجی می‌فرستیم. حالا همونطور که توی خط ۱۰ می‌بینیم، تونستیم full_name رو مثل یک پراپرتی معمولی فراخونی کنیم. بنابراین برای داشتن اسم کامل دیگه لازم نیست نام و نام‌خانوادگی رو به هم بچسبونیم.

نکته‌ای که هنگام استفاده از متد Getter باید در نظر داشته باشیم اینه که برای این متد نباید هیچ پارامتری تعریف کنیم.

 

پراپرتی Setter

Setter هم یک پراپرتی هست که بصورت یک تابع تعریف میشه و زمانی اجرا میشه که می‌خوایم یک پراپرتی رو از بیرون مقداردهی کنیم. از Setter زمانی استفاده می‌کنیم که می‌خوایم کنترل بیشتری هنگام مقدار دادن به یک پراپرتی داشته باشیم.

مثال زیر رو در نظر بگیرید که هنوز به اون Setter اضافه نکردیم و می‌خوایم از بیرون از آبجکت person، نام و نام‌خانوادگی اون رو عوض کنیم:

const person = {
  first_name: 'John',
  last_name:  'Doe',

  get full_name() {
    return `${this.first_name} ${this.last_name}`;
  }
};

>> person.first_name = "Jakub";
>> person.last_name = "Blaszczykowski";

alert(person.full_name); // Jakub Blaszczykowski

در حالت عادی باید بصورت جداگونه به هر دو پراپرتی مقدار بدیم. اما با استفاده از یک Setter (خط ۹ کد زیر) می‌تونیم این کار رو کوتاه‌تر کنیم:

const person = {
  first_name: 'John',
  last_name:  'Doe',

  get full_name() {
    return `${this.first_name} ${this.last_name}`;
  },

  set full_name(value) {
    if (value) {
      [this.first_name, this.last_name] = value.split(' ');
    } else {
        alert("Fullname can't be empty");
    }
  },
};

person.full_name = "Jakub Blaszczykowski";

alert(person.first_name); // Jakub

همونطور که می‌بینیم، توی خط ۱۸ داریم به پراپرتی full_name مقدار می‌دیم. هنگام مقدار دادن به این پراپرتی، اگه یک متد Setter به همین اسم توی آبجکت وجود داشته باشه اجرا خواهد شد. در غیر این صورت پراپرتی full_name بصورت مستقیم مقداردهی میشه.

توی آبجکت و توی خط ۹، ما با استفاده از کلمه کلید set یک متد Setter به اسم full_name درست کردیم که زمانی اجرا میشه که از بیرون مثل خط ۱۸ مقداردهی بشه.

نکته‌ای که هنگام استفاده از متد Setter باید در نظر داشته باشیم اینه که همیشه باید برای این متد، یک پارامتر تعریف کنیم.

توی خط ۱۱ کد بالا، از Array Destructuring استفاده کردیم. برای آشنایی بیشتر می‌تونید سوال ۴۷ سوالات مصاحبه جاوااسکریپت رو بخونید:

 

ساختن متدهای Getter و Setter از بیرون از آبجکت

اگه بخوایم از بیرون از آبجکت، متدهای Getter و Setter بسازیم، از متد defineProperty بصورت زیر استفاده می‌کنیم:

const person = {}

Object.defineProperty(person, 'full_name', {
  set(value) {
    [this.first_name, this.last_name] = value.split(' ');
  },
  get() {
    return `${this.first_name} ${this.last_name}`;
  }
});

person.full_name = "John Doe";

alert(person.full_name);  // John Doe
alert(person.first_name); // John
alert(person.last_name);  // Doe

 

چرا از Getter و Setter استفاده کنیم؟ 🤔

همونطور که دیدیم با استفاده از این ویژگی، حجم کدنویسی ما کمتر شد و همچنین تونستیم کنترل بیشتری روی نحوه مقداردهی و نمایش‌دادن پراپرتی‌ها داشته باشیم. با استفاده از Getter و Setter خیلی از کارها پشت‌پرده انجام میشه و این موضوع برای کسی که با کدها آشنایی نداره، ممکنه گیج‌کننده باشه. پس بهتره از اون زمانی استفاده کنیم که واقعاً نیاز هست.

 

امیدوارم از این قسمت هم استفاده کرده باشید. روزتون خوش 😉✌️

 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

https://www.w3schools.com/js/js_object_accessors.asp

https://javascript.info/property-accessors