بیایید از ساختار دادههای منحصر به فرد دور شویم و درباره حلقهزدن در آنها حرف بزنیم.
در فصل قبل ما متدهای map.keys()
، map.values()
، map.entries()
را دیدیدم.
این متدها کلی هستند و یک توافق عمومی برای استفاده از آنها در ساختارهای داده وجود دارد. اگر ما هر زمان بخواهیم ساختار دادهی خودمان را بسازیم، باشد آنها را نیز پیادهسازی کنیم.
اینها برای ساختارهای زیر پشتیبانی میشوند:
Map
Set
Array
شیءهای ساده هم متدهای مشابه را پشتیبانی میکنند اما سینتکس آن کمی فرق دارد.
متدهای Object.keys، values، entries
برای شیءهای ساده، متدهای زیر موجود هستند:
- Object.keys(obj) – آرایهای از کلیدها برمیگرداند.
- Object.values(obj) – آرایهای از مقدارها برمیگرداند.
- Object.entries(obj) – آرایهای از
[key, value]
برمیگرداند.
لطفا تفاوتها را در نظر داشته باشید (برای مثال در مقایسه با map):
Map | شیء | |
---|---|---|
سینتکس فراخوانی | map.keys() |
Object.keys(obj) ، اما obj.keys() نه |
برمیگرداند | حلقهپذیر | آرایه «واقعی» |
اولین تفاوت این است که ما باید Object.keys(obj)
را صدا بزنیم نه obj.keys()
.
اما چرا؟ دلیل اصلی آن انعطافپذیری است. به یاد داشته باشید، شیءها پایه تمام ساختارهای پیچیده در جاوااسکریپت هستند. پس ما میتوانیم خودمان یک شیء مانند data
داشته باشیم که متد data.keys()
خودش را پیادهسازی کند. و ما همچنان میتوانیم Object.values(data)
را برای آن فراخوانی کنیم.
تفاوت دوم این است که متدهای Object.*
شیءهای «واقعی» آرایه را برمیگردانند نه فقط یک حلقهپذیر. این موضوع دلایل تاریخی دارد.
برای مثال:
let user = {
name: "John",
age: 30
};
Object.keys(user) = ["name", "age"]
Object.values(user) = ["John", 30]
Object.entries(user) = [ ["name","John"], ["age",30] ]
اینجا یک مثال از استفاده کردن از Object.values
برای حلقهزدن درون مقدارهای ویژگیها داریم:
let user = {
name: "John",
age: 30
};
// حلقهزدن در مقدارها
for (let value of Object.values(user)) {
alert(value); // سپس 30 ،John
}
درست مانند یک حلقه for..in
، این متدها ویژگیهایی که از Symbol(...)
به عنوان کلید استفاده میکنند را نادیده میگیرند.
معمولا این موضوع مشکلی ایجاد نمیکند. اما اگر ما کلیدهای سمبلی را هم بخواهیم، یک متد جداگانه Object.getOwnPropertySymbols هم وجود دارد که یک آرایه از کلیدهای سمبلی را برمیگرداند. همچنین یک متد Reflect.ownKeys(obj) وجود دارد که تمام کلیدها را برمیگرداند.
تغییر شکل دادن شیءها
شیءها تعداد زیادی از متدهایی که برای آرایه وجود دارد را ندارند، مانند map
، filter
و بقیه آنها.
اگر ما بخواهیم آنها را اعمال کنیم، میتوانیم از متد Object.entries
و سپس از Object.fromEntries
استفاده کنیم:
- از
Object.entries(obj)
برای گرفتن آرایهای از جفتهای کلید/مقدار ازobj
استفاده کنید. - برای تغییر شکل دادن این جفتهای کلید/مقدار، از متدهای آرایه روی آن آرایه استفاده کنید، برای مثال
map
. - از
Object.fromEntries(array)
بر روی آرایه حاصل برای برگرداندن آن به یک شیء استفاده کنید.
برای مثال، ما یک شیء حاوی قیمتها را داریم و میخواهیم آنها را دو برابر کنیم:
let prices = {
banana: 1,
orange: 2,
meat: 4,
};
let doublePrices = Object.fromEntries(
// هر جفت را به جفت جدید دیگری تبدیل میکنیم map قیمتها را به یک آرایه تبدیل میکنیم و با استفاده از
// شیء را بازمیگرداند fromEntries و سپس متد
Object.entries(prices).map(entry => [entry[0], entry[1] * 2])
);
alert(doublePrices.meat); // 8
ممکن است در نگاه اول سخت بنظر برسد اما بعد از اینکه یکی دوبار از آن استفاده کنید فهم آن راحت میشود. ما میتوانیم زنجیرههای قدرتمندی از تغییر شکل دادن را با این روش بسازیم.