علاوه بر انواع دادهی اولیه مانند number و string، نوع دادهی مهم دیگری هم در JavaScript وجود دارد که به آن object میگویند.
شیءها مجموعههایی از جفتهای کلید-مقدار هستند.
به همین دلیل، میتوان از آنها بهعنوان چیزی استفاده کرد که در زبانهای دیگر معمولاً «map» یا «dictionary» نامیده میشود.
در زبانهای دیگر، اغلب همهی مقادیر یک map باید از یک نوع داده باشند.
در JavaScript، فقط نوع کلید محدود است: باید یک string باشد.
مقادیر داخل یک شیء میتوانند نوعهای متفاوتی داشته باشند.
میتوانند انواع اولیه مانند عدد باشند، اما همچنین آرایه، شیءهای دیگر یا حتی تابع.
همین موضوع شیءها را بسیار انعطافپذیر میکند، بهگونهای که در JavaScript در برنامهنویسی شیءگرا (OOP) هم نقشی کلیدی دارند.
در ادامه، بر شیءها بهعنوان مجموعه یا map تمرکز خواهیم کرد. سایر کاربردهای شیءها در مفاهیم دیگر پوشش داده میشود؛ برای نمونه کلاسها را ببینید.
شیء را بهصورت لیترال و با آکولاد میسازید. همچنین میتوانید چند ورودی (جفت کلید-مقدار) را هم بهطور مستقیم بگنجانید. برای این کار، اول کلید را بنویسید، بعد یک دو نقطه و سپس مقدار را.
const emptyObject = {};
const obj = {
favoriteNumber: 42,
greeting: 'Hello World',
useGreeting: true,
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
fruits: ['melon', 'papaya'],
addNumbers: function (a, b) {
return a + b;
},
};
ویرگول انتهایی پس از آخرین ورودی در JavaScript اختیاری است. میتوانید دربارهی مزایای استفاده از آن اینجا بخوانید.
ممکن است برایتان سؤال باشد چرا کلیدها در گیومه قرار نمیگیرند، هرچند قرار است string باشند.
این یک شکل کوتاهنویسی است.
اگر کلید از قواعد نامگذاری یک شناسه در JavaScript پیروی کند، میتوانید گیومهها را حذف کنید.
برای کلیدهایی که در اسمشان کاراکترهای ویژه دارند، باید از همان نگارش معمول رشته استفاده کنید.
const obj = {
'1keyStartsWithNumber': '...',
'key/with/slashes': '...',
'key-with-dashes': '...',
'key with spaces': '...',
'#&()[]{}èä樹keyWithSpecialChars': '...',
};
اغلب میخواهید هنگام تعریف یک شیء، متغیرهای موجود را هم اضافه کنید.
این کار اغلب به جفتهای کلید-مقداری مانند name: name منجر میشود.
JavaScript یک شکل کوتاهنویسی دارد که با آن میتوانید فقط name را بنویسید.
یک شکل کوتاهنویسی هم برای تعریف تابع در یک شیء وجود دارد.
در آن میتوانید دو نقطه و کلیدواژهی function را حذف کنید.
const x = 1;
const y = 2;
const obj = {
x: x,
y: y,
calcSum: function (a, b) {
return a + b;
},
};
// Can be shortened to ...
const obj = {
x,
y,
calcSum(a, b) {
return a + b;
},
};
اگر میخواهید یک لیترال شیء بسازید که اسم کلیدش در یک متغیر ذخیره شده یا از یک عبارت بهدست آمده است، باید متغیر یا عبارت را داخل کروشه قرار دهید.
const key = 'greeting';
const obj = {
[key]: 'hello world',
};
console.log(obj);
// => { greeting: 'hello world' }
دو روش برای بازیابی مقدار یک کلید مشخص وجود دارد: نگارش نقطهای و نگارش کروشهای.
const obj = { greeting: 'hello world' };
obj.greeting;
// => hello world
obj['greeting'];
// => hello world
// Bracket notation also works with variables.
const key = 'greeting';
obj[key];
// => hello world
استفاده از نگارش نقطهای بهعنوان کوتاهنویسی همان محدودیت حذف گیومهها را دارد. فقط زمانی کار میکند که کلید از قواعد نامگذاری شناسه پیروی کند.
اگر بخواهید کلیدی را بازیابی کنید که در شیء وجود ندارد، JavaScript مقدار undefined را برمیگرداند.
برای جزئیات بیشتر در این باره، Null و Undefined را ببینید.
اگر بخواهید مقداری را از یک شیء تودرتو بازیابی کنید، میتوانید کلیدها را زنجیره کنید.
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};
obj.address.city;
// => 'Batticaloa'
obj['address']['city'];
// => 'Batticaloa'
// Notations can also be mixed.
obj.address['city'];
// => 'Batticaloa'
میتوانید با استفاده از عملگر انتساب = مقداری را اضافه یا تغییر دهید.
باز هم دو نگارش نقطهای و کروشهای در دسترس هستند.
const obj = { greeting: 'hello world' };
obj.greeting = 'Hi there!';
obj['greeting'] = 'Welcome.';
obj.newKey1 = 'new value 1';
obj['new key 2'] = 'new value 2';
const key = 'new key 3';
obj[key] = 'new value 3';
میتوانید با استفاده از کلیدواژهی delete یک جفت کلید-مقدار را از یک شیء حذف کنید.
const obj = {
key1: 'value1',
key2: 'value2',
};
delete obj.key1;
delete obj['key2'];
توجه داشته باشید که هرچند برای کلیدهای ناموجود undefined برگردانده میشود، تنظیم یک کلید روی undefined آن ورودی را حذف نمیکند.
همیشه بهجای آن از delete استفاده کنید.
میتوانید با متد hasOwnProperty بررسی کنید که آیا کلید مشخصی در یک شیء وجود دارد یا نه.
const obj = { greeting: 'hello world' };
obj.hasOwnProperty('greeting');
// => true
obj.hasOwnProperty('age');
// => false
hasOwnProperty برای کلیدهای ارثبریشده مقدار false را برمیگرداند.
این معمولاً رفتار مورد انتظار است.
اگر میخواهید کلیدهای ارثبریشده را هم در بررسی وجود لحاظ کنید، میتوانید بهجای آن از عملگر in استفاده کنید.
یک حلقهی ویژهی for...in وجود دارد که روی همهی کلیدهای یک شیء پیمایش میکند.
const obj = {
name: 'Ali',
age: 65,
};
for (let key in obj) {
console.log(key, obj[key]);
}
// name Ali
// age 65
به نظر میرسد که for...in همیشه کلیدها را به همان ترتیبی که ظاهر شدهاند یا به شیء اضافه شدهاند (ترتیب درج) بازدید میکند.
با این حال، نباید به این موضوع تکیه کنید، چون موارد ویژهای وجود دارد که در آنها ترتیب با ترتیب درج تفاوت دارد.
همیشه کدتان را طوری بنویسید که گویی ترتیب دلخواه است.
اگر به ترتیبی قابلاعتماد نیاز دارید، بهجای شیء از یک Map یا یک [آرایه][concept-arrays]ی تودرتو استفاده کنید.
حلقهی for…in در صورتی که شیء کلیدهای ارثبریشده داشته باشد، یک دام دارد.
آنها هم توسط حلقهی for...in بازدید میشوند.
معمولاً میخواهید از این وضعیت دوری کنید، بنابراین باید همانطور که در زیر نشان داده شده از آنها عبور کنید.
for (let key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}
// ...
}
JavaScript همچنین یک حلقهی for...of دارد، مثلاً برای پیمایش روی آرایهها.
نکتهی مهم این است که for...in و for...of قابل جایگزینی با یکدیگر نیستند؛ برای جزئیات بیشتر مستندات MDN را ببینید.
شیء توکار Object متدهای کمکیای ارائه میدهد که همهی کلیدها، مقادیر یا ورودیهای یک شیء مشخص را بهصورت آرایه برمیگرداند.
const obj = {
name: 'Ali',
age: 65,
};
Object.keys(obj);
// => [ 'name', 'age' ]
Object.values(obj);
// => [ 'Ali', 65 ]
Object.entries(obj);
// => [ [ 'name', 'Ali' ], [ 'age', 65 ] ]
ممکن است متوجه شده باشید که یک شیء خالی در JavaScript کاملاً خالی نیست.
برای مثال، متد hasOwnProperty و متدهای دیگری مانند toString را در خود دارد.
معمولاً این موضوع مشکلی ایجاد نمیکند، اما اگر روزی به ساختن یک شیء واقعاً خالی نیاز داشتید، از یک شیء null استفاده کنید که میتوان آن را با Object.create(null) ساخت.