تغییرناپذیر (Immutable) کردن آبجکت‌ها در جاوااسکریپت

تو این مطلب طریقه‌ Immutable کردن آبجکت‌ها توی زبان برنامه‌نویسی جاوااسکریپت رو توضیح میدیم. قبل از هر چیز بگم که Immutable در زبان فارسی به معنی تغییرناپذیر بودن هست و ما هم از همین کلمه استفاده می‌کنیم.




تغییرناپذیر بودن یعنی چی؟

خوب همون‌طور که از اسمش پیداست، به معنی غیر قابل‌تغییر بودن هست. یعنی زمانی که یک مقدار (value) به یک متغیر داده میشه، دیگه اون مقدار قابل تغییر کردن نیست.

تغییر ناپذیر کردن آبجکت‌ها تو زبان جاوااسکریپت

همون‌طور که می‌دونید، تو زبان جاوااسکریپت یه کلمه کلیدی هست به نام const که وقتی از این کلمه برای ایجاد یه متغیر استفاده می‌کنیم، اون متغیر تغییرناپذیر میشه:


const name = "Behzad"; 
name = "Another beautiful name";    //TypeError: 'name'  is read-only

اما شاید متوجه این موضوع شده باشید که وقتی پای آبجکت‌ها میاد وسط، قضیه یه مقدار فرق می‌کنه:

const person = { 'name': 'Behzad' };

person.name = 'Aria';
console.log(person);

// The person will be:
{'name': 'Aria'};

خوب به نظر میاد کلمه کلیدی const، هیچ کمکی به تغییرناپذیر کردن آبجکت ما نکرد!

راه حل؟

خوب الان وقتشه که Object.freeze رو بهتون معرفی کنم!

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

  • شما قادر به اضافه کردن property به آبجکت نیستید.
  • مسلما قادر به حذف کردن property از هم آبجکت نیستید.
  • قادر به تغییر دادن مقدار یک property هم نیستید!؟ (یا شایدم هستید!)


خوب اجازه بدید خیلی سریع این چند مورد رو امتحان کنیم.

اول از همه باید آبجکت رو فریز کنیم:


const person = { 
    name: 'Behzad Pournouri', 
    age: 25, 
    address: { 
    city: 'Tehran' 
} }; 
// person and frozenPerson are the reference to the same object. 
const frozenPerson = Object.freeze(person);


نکته‌ی مهمی که اینجا باید گفته بشه این هست که الان person و frozenPerson دقیقا یکی هستن. یعنی به یک نقطه از حافظه اشاره می‌کنن.

اضافه کردن یک property به اسم salary به آبجکت:


person.salary = 68761182; 

frozenPerson.salary = 68761182;


   // person after adding property, Salary       
     { name: 'Behzad Pournouri', 
     age: 25,      
     address: {      
      city: 'Tehran' 
       } }
       
 // frozenPerson after adding property, Salary 
{ name: 'Behzad Pournouri',       
age: 25,            
address: {             
city: 'Tehran'        
 } } 
 


حذف کردن یک property از آبجکت:


delete person.name; 


  // person after deleting name 
 { name: 'Behzad Pournouri',       
  age: 25,             
  address: {              
  city: 'Tehran'          
  } }  


تغییر دادن مقدار یک property:

خوب بذارید همین اولش بگم که ما قادر به عوض کردن مقدار name نیستیم ولی مقدار address رو می‌تونیم عوض کنیم. برای غیر قابل‌تغییر کردن مقدار ‌address بازم باید همون روش فریز کردن رو به‌کار ببریم:


person.name = 'Aria'; 


// person after changing name 
  { name: 'Behzad Pournouri',         
   age: 25,                
   address: {                 
   city: 'Tehran'             
   } }   
   
   
person.address.city = 'Shiraz'; 


// person after changing address 
   { name: 'Behzad Pournouri',             
   age: 25,                   
    address: {                    
     city: 'Shiraz'                 
} }    


خوب متاسفانه یا خوشبختانه، برای تغییر‌ناپذیر کردن address، باید دوباره از همون روش فریز کردن استفاده کنیم:


// Now the Inner object is also frozen
Object.freeze(person.address)

// You can test if the object is frozen
console.log(Object.isFrozen(person));  // returns true
console.log(Object.isFrozen(frozenPerson)); // returns true


نتیجه‌گیری

خوب همون‌طور که دیدید Object.freeze به ما کمک می‌کنه تا یک آبجکت تغییرناپذیر داشته باشیم. تو دنیای برنامه‌نویسی، به‌خصوص برنامه نویسی شی‌گرا، این موضوع خیلی طبیعی هست که ما یک آبجکت داشته باشیم و اجازه تغییر کردن به اون آبجکت رو ندیم. مثلا می‌تونه یه API باشه که نباید هیچ property ازش حذف یا بهش اضافه بشه.

روش‌های دیگه‌ای هم برای غیر قابل‌تغییر کردن یک آبجکت وجود دارن، ولی توی این مطلب فقط به یکی از اون‌ها اشاره کردم.

حرف آخر

خوب این اولین مطلب من تو سایت ویرگول بود. امیدوارم با وسواس خونده باشید و مشکلاتم رو تو بخش نظرات بهم بگید. پست‌های بعدی بازم تو زمینه برنامه‌نویس (و احتمالا جاوااسکریپت) خواهد بود. اگر دوست داشتید من رو دنبال کنید تا مطالب بعدی رو از دست ندید.