مقدمه

در زبان جاوااسکریپت، اشیاء یا objects نقش بسیار مهمی دارند و بخش عمده‌ای از ساختارها و کدها بر مبنای همین مفهوم طراحی می‌شوند. اگرچه جاوااسکریپت انواع داده‌های اولیه یا Primitive را دارد، اما برای مدیریت داده‌های پیچیده‌تر و ذخیره چندین مقدار مرتبط، به اشیاء نیاز داریم. نکته‌ی مهمی که باید بدانید این است که در جاوااسکریپت هر مقداری که به یکی از نوع‌های Primitive متعلق نباشد، یک Object است. در این درس با روش‌های ساخت و استفاده از اشیاء آشنا می‌شوید.

روش‌های تعریف اشیاء

هر شیء در جاوااسکریپت مجموعه‌ای از پراپرتی‌ها (property) است و هر پراپرتی از یک کلید (key) و یک مقدار (value) تشکیل می‌شود. به بیان ساده، می‌توانید یک شیء را مانند یک قفسه فرض کنید که هر پرونده‌اش یک نام (کلید) دارد و داخل هر پرونده یک مقدار ذخیره شده است. این پراپرتی‌ها می‌توانند شامل داده‌های ساده مثل عدد و رشته یا حتی توابع باشند که به آن‌ها متد (method) می‌گوییم.

تشبیه اشیا به ققسه‌های حاوی پرونده‌ها

در جاوااسکریپت می‌توانید به دو روش اصلی شیء بسازید: با استفاده از Object Literal یا با Object Constructor. معمولاً روش اول به دلیل سادگی و خواناییِ بیشتر، رایج‌تر است.

Object Literal: سریع‌ترین و رایج‌ترین راه ساخت شیء است. کافی است نام متغیر را انتخاب کنید و آن را با یک جفت آکولاد مقداردهی کنید. داخل آکولادها می‌توانید هر تعداد پراپرتی دلخواه به صورت key: value بنویسید. مثال:

Copy Icon JAVASCRIPT
let user = {
  name: "Ali",
  age: 30,
  email: "ali@example.com"
};

Object Constructor: در این روش، شیء با استفاده از سازنده داخلی Object ساخته می‌شود. این روش در گذشته کاربرد بیشتری داشت اما همچنان می‌توانیم از آن استفاده کنیم:

Copy Icon JAVASCRIPT
let user = new Object(); // شیء خالی
user.name = "Ali";
user.age = 30;

با این روش ابتدا شیء ساخته می‌شود و سپس به آن پراپرتی‌ اضافه می‌کنیم. البته ساخت یک شیء خالی با استفاده از روش اول هم ممکن است؛ کافیست آکولاد را خالی بگداریم. برای مثال، گزاره‌ی زیر باعث ایجاد یک شیء خالی با نام user می‌شود که بعداً می‌توانیم پراپرتی‌هایی را به آن اضافه کنیم.

let user = {};

پراپرتی‌ها و مقادیر در اشیاء

همانطور گه گفته شد، هر پراپرتی در یک شیء از دو بخش تشکیل شده: کلید (key) که معمولاً یک رشته است و مقدار (value) که می‌تواند از هر نوع داده‌ای باشد. برای تعریف پراپرتی کافی است آن را داخل آکولاد و به فرم key: value بنویسید.

مقادیر پراپرتی‌ها می‌توانند انواع مختلفی باشند. حتی می‌توانید مقدار یک پراپرتی را برابر یک تابع قرار دهید (که در آینده با عنوان متد به آن برمی‌گردیم).

Copy Icon JAVASCRIPT
let book = {
  title: "JavaScript For Web",
  pages: 900,
  available: true
};

در اینجا شیء book را با سه پراپرتی با نام‌های title، pages و available تعریف کرده‌ایم که اولی یک مقدار رشته‌ای دارد، دومی یک مقدار عددی و سومی یک مقدار بولین.
همچنین می‌توانید بعد از ساخت شیء، پراپرتی‌های جدیدی به آن اضافه کنید یا هر زمان که بخواهید یک پراپرتی را حذف کنید. روش انجام این کارها را در ادامه خواهیم دید.

دسترسی و ویرایش مقادیر پراپرتی‌ها

برای دسترسی به مقدار یک پراپرتی از دو روش استفاده می‌شود: dot notation (نقطه‌گذاری) و bracket notation (براکت‌گذاری). اما این دو روش چه تفاوتی با هم دارند و از هر کدام در چه شرایطی استفاده می‌شود؟

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

Copy Icon JAVASCRIPT
console.log(user.name);
user.age = 31;

اما اگر نام پراپرتی شامل فاصله یا کاراکترهای خاص باشد، باید از براکت استفاده کنید:

Copy Icon JAVASCRIPT
user["favorite color"] = "green";
console.log(user["favorite color"]);

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

Copy Icon JAVASCRIPT
let key = "email";

let user = {
    name: 'john',
    email: 'john@example.com'
};

console.log(user[key]);  // john@example.com

در این مثال، مقدار متغیر key برابر با "email" است و با استفاده از براکت‌گذاری، مقدار پراپرتی متناظر در شیء user خوانده می‌شود. اگر مقدار key را تغییر دهید، پراپرتی دیگری خوانده خواهد شد.

افزودن و حذف پراپرتی‌ها

یکی از ویژگی‌های مهم اشیاء در جاوااسکریپت این است که پویا هستند؛ یعنی می‌توانید در هر لحظه پراپرتی جدید به آن‌ها اضافه کنید یا پراپرتی‌ای را حذف نمایید. کافی است با dot notation یا bracket notation پراپرتی جدید را مقداردهی کنیم. برای حذف یک پراپرتی هم می‌تواینم از عملگر delete استفاده کنیم.

Copy Icon JAVASCRIPT
user.isAdmin = true;
delete user.age;
user["level"] = 2;

اگر سعی کنید مقدار پراپرتی حذف شده را بخوانید، مقدار undefined به شما برگردانده می‌شود. این قابلیت باعث انعطاف‌پذیری بالای اشیاء می‌شود و یکی از دلایل استفاده گسترده از object در جاوااسکریپت است.

گاهی اوقات می‌خواهیم بدانیم آیا یک شیء دارای یک پراپرتی مشخص هست یا نه. این کار هم به دو روش قابل انجام است. در جاوااسکریپت، بر خلاف خیلی زبان‌های دیگر، دسترسی به پراپرتیِ ناموجود با خطا همراه نیست، بلکه به برگشت مقدار undefined منجر می‌شود. بنابراین، برای تست وجود یا عدم وجود یک پراپرتی کافیست مقدار آن را با undefined مقایسه کنیم. اما به جای این کار می‌تواینم از یک عملگر خاص با نام in هم استفاده کنیم. در کد زیر از هر دو روش استفاده شده است.

Copy Icon JAVASCRIPT
if (user.isAdmin !== undefined) {    
    console.log("User is admin");
} else {   
    console.log("User is not admin");
}
if ("level" in user) {
    console.log("User level is", user.level);
}
if ("age" in user) {
    console.log("User age is", user.age);
}
else {
    console.log("User age is not defined");
}

در این مثال، ابتدا بررسی می‌کنیم که آیا پراپرتی isAdmin وجود دارد یا خیر. اگر وجود داشته باشد، پیغام مربوطه چاپ می‌شود. سپس با استفاده از عملگر in بررسی می‌کنیم که آیا پراپرتی level و age در شیء user وجود دارند یا خیر.

حلقه for..in

برای تکرار روی پراپرتی‌های یک شیء می‌توانیم از حلقه for..in استفاده کنیم. این حلقه به ما این امکان را می‌دهد که به سادگی روی تمام کلیدهای یک شیء پیمایش کنیم. در کد زیر یک مثال از استفاده از حلقه for..in برای نمایش تمام پراپرتی‌های یک شیء آورده شده است.

Copy Icon JAVASCRIPT
for (let key in user) {
    console.log(key, user[key]);
}

در این مثال، حلقه for..in روی تمام پراپرتی‌های شیء user تکرار می‌کند و نام هر پراپرتی (کلید) و مقدار آن را چاپ می‌کند. این روش بسیار مفید است، به‌خصوص زمانی که نمی‌دانیم یک شیء چه پراپرتی‌هایی دارد یا تعداد آن‌ها زیاد است.

اختصار در نوشتن مقدار پراپرتی‌ها

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

Copy Icon JAVASCRIPT
let name = 'Arash';
let age = 25;
let user = {
    name, // name: name
    age,  // age: age
    email: 'arash@example.com'
};