Map در جاوا اسکریپت متشکل از مجموعهای از جفتهای «کلید – مقدار» (Key – Value) است. Map در واقع بسیار شبیه به «شی» (Object) بوده ولی چند تفاوت کلیدی با آن دارد. بحث Map در زبان برنامه نویسی جاوا اسکریپت از مباحث مهم و در عین حال جذابی است که در این مطلب آموزشی از مجله تم آف پوشش داده شده است تا کاربران در پایان، با مطالعه این مقاله درک مطلوبی از Map در جاوا اسکریپت بدست آورند.
Map در جاوا اسکریپت چیست ؟
قبل از اینکه «جاوا اسکریپت مدرن» (ES6) معرفی شود، برنامه نویسان مجبور بودند برای نگاشت کلیدها به مقادیر، از «شی» (Object) استفاده کنند. شی در جاوا اسکریپت به آنها اجازه میداد تا کلیدها را به مقادیر نگاشت کرده و نوع دادهها اعم از دادههای رشتهای، بولی، عددی و غیره اهمیت نداشت. با این حال، استفاده از شی برای «نگاشت» (Map) ممکن است بر کدهای جاوا اسکریپت اثرات جانبی بگذارد.
در این رابطه، توجه به دو اصل زیر در جاوا اسکریپت کلاسیک بسیار مهم است. این ۲ اصل در ادامه فهرست شدهاند.
- اشیای جاوا اسکریپت حاوی کلیدی پیشفرض مانند «Prototype» بودند.
- کلیدهای اشیا مجاز نبودند از هر نوعی باشند و به عبارت دیگر، تنها مجاز بودند یا از نوع رشتهای و یا از نوع «Symbol» باشند.
در جاوا اسکریپت مدرن نوع دادهای از جنس «Collection» به نام «Map» فراهم شده که برای رویارویی با این کاستیها در جاوا اسکریپت کلاسیک معرفی شده است.
طبق تعریف، شی Map جفتهای کلید-مقدار را نگهداری میکند. کلیدها در یک مجموعهی Map منحصربهفرد هستند یا به بیان دیگر، یک کلید در شی Map تنها یک بار ظاهر میشود. کلیدها و مقادیر در Map میتوانند هر مقداری داشته باشند.
وقتی در طول یک شیِ Map پیمایش انجام میشود، در هر تکرار، آرایهای حاوی ۲ عضو به صورت [key, value]
بازگردانده خواهد شد. ترتیب تکرار از ترتیب درج تبعیت میکند. ترتیب درج هم با ترتیبی مطابقت دارد که در آن هر جفت کلید-مقدار زودتر در داخل Map به وسیله متُد set()
درج شده است.
سیتنکس Map در جاوا اسکریپت
سینتکس Map در زبان جاوا اسکریپت به صورت زیر است:
let map = new Map([iterable]);
Map در جاوا اسکریپت در واقع شیئی قابل پیمایش یا «تکرارپذیر» (Iterable) را میپذیرد که عناصر آن جفتهای کلید-مقدار هستند.
متدهای کاربردی Map در جاوا اسکریپت کدامند؟
Map حاوی متدهای بسیاری است که از مهمترین آنها میتوان به فهرست موارد زیر اشاره کرد.
- clear()
: این متد تمامی عنصرها را از شی Map حذف خواهد کرد.
- delete(key)
: کار این متد حذف یک عنصر مشخص شده توسط کلید است. اگر عنصر مربوطه در Map موجود باشد، آن را باز میگرداند، در غیر این صورت، مقدار بازگردانده شده false
خواهد بود.
- entries()
: این متد، شی «تکرارشونده» (Iterator) جدیدی را باز میگرداند که حاوی آرایهای از [key, value]
برای هر عنصر در شی Map است. ترتیب اشیا در Map با ترتیب درج یکسان است.
- forEach(callback[, thisArg])
: «بازفراخوانی» (Callback) را برای هر جفت کلید-مقدار در Map به ترتیب درج فراخوانی میکند. میتوان به وسیله پارامتر اختیاری thisArg
مقدار this
را برای هر Callback مشخص کرد.
- get(key)
: این متد مقداری را بازمیگرداند که به کلید مرتبط است. اگر کلید وجود نداشته باشد، مقدار «تعریف نشده» (Undefined) باز گردانده خواهد شد.
- has(key)
: این متد در صورتی که مقداری مرتبط با کلید موجود باشد، آن را باز میگرداند و در غیر اینصورت مقدار false را باز میگرداند.
- keys()
: این متد «تکرارپذیر» (Iterator) جدیدی را بازمیگرداند که حاوی کلیدهای عنصر به ترتیبی است که درج شدهاند.
- set(key, value)
: کار این متد تعیین مقدار کلید در شی Map است. همچنین این متد خودِ شی Map را بازمیگرداند، بنابراین میتوان این این متُد را با سایر متدها به اصطلاح زنجیر کرد.
- values()
: این متد شی Iterator جدیدی را باز میگرداند که این شی حاوی مقادیری برای هر عنصر به ترتیب درج است.
مثال هایی از Map در جاوا اسکریپت
در این بخش چند مثال کاربردی از Map در Javascript ارائه شده است تا بتوان درک بهتری را نسبت به این مفهوم بدست آورد.
مثال ساخت شی Map جدید
در مثال زیر، فرض بر این است که فهرستی از اشیای user
به صورت زیر موجود هستند.
let Ali = {name: 'Ali Ahmadi'},
Reza= {name: 'Reza Karimi'},
Amir= {name: 'Amir Mohammadi'};
اگر بخواهیم برای کاربران و نقش آنها، Map ایجاد کنیم، باید این کار را به صورت زیر انجام داد.
let userRoles = new Map();
در قطعه کد بالا، userRoles
«وهلهای» (Instance) از Map است و نوع آن همانطور که در مثال زیر نشان داده شده است، از نوع «شی» ( object
) به حساب میآید.
1
2
console.log(typeof(userRoles)); // object
console.log(userRoles instanceof Map); // true
مثال اضافه کردن عناصر به Map
برای تخصیص نقش به کاربران باید از متد set()
به صورت زیر استفاده کرد.
userRoles.set(Ali, 'admin');
در قطعه کد بالا، متد set()
نقش admin
را به کاربری به نام Ali
نگاشت میکند. همچنین از آنجا که متد set()
قابل زنجیر شدن است، میتوان همانطور که در قطعه کد زیر آمده است، کدهای کمتری نوشت.
userRoles.set(Reza, 'editor')
.set(Amir, 'subscriber');
مثال مقدار دهی به Map با شی تکرارپذیر
همانطور که پیشتر بیان شد، میتوان شیئی «تکرارپذیر» (Iterable) را به سازنده Map()
ارسال کرد.
let userRoles = new Map([
[Ali, 'admin'],
[Reza, 'editor'],
[Amir, 'subscriber']
]);
مثال دریافت عناصر از Map با کلید
اگر بخواهیم نقش Ali
را بدانیم، باید به صورت زیر از متد get()
برای این منظور استفاده کنیم.
userRoles.get(Ali); // admin
اگر کاربر کلیدی را ارسال کند که اصلاً این کلید وجود ندارد، در نتیجه متد get()
، مقدار undefined
(تعریف نشده) را بازمیگرداند:
let foo = {name: 'Amin'};
userRoles.get(Amin); //undefined
مثال بررسی وجود عناصر با کلید
برای بررسی وجود کلید در Map، از متد has()
مانند مثال زیر استفاده میشود.
userRoles.has(Amin); // false
userRoles.has(Reza); // true
مثال بدست آوردن تعداد عناصر موجود در Map
برای محاسبه تعداد عناصر Map در Javascript باید از خصیصه size
به صورت زیر استفاده کرد.
console.log(userRoles.size); // 3
مثال عملیات تکرار روی کلیدهای Map
برای دریافت کلیدهای شی Map، باید از متدی به نام keys()
استفاده کرد. متد keys()
«شی تکرارکننده» (Iterator Object) جدیدی را بازمیگرداند که این شی حاوی کلیدهای عناصر در Map است.
در مثال زیر نام کاربری کاربران موجود در شی مپ userRoles
نمایش داده میشود.
let Ali= { name: 'Ali Ahmadi' },
Reza= { name: 'Reza Karimi' },
Amir= { name: 'Amir Mohammadi' };
let userRoles = new Map([
[Ali, 'admin'],
[Reza, 'editor'],
[Amir, 'subscriber'],
]);
for (const user of userRoles.keys()) {
console.log(user.name);
}
خروجی کد بالا به صورت زیر است:
Ali Ahmadi
Reza karimi
Zahra kazemi
مثال پیمایش در مقادیر map
به طور مشابه میتوان متد values()
برای دریافت یک شی Iterator استفاده کرد که حاوی مقادیری برای تمام عناصر در Map است.
let Ali = { name: 'Ali Ahmadi' },
Reza= { name: 'Reza Karimi' },
Amir= { name: 'Amir Mohammadi' };
let userRoles = new Map([
[Ali, 'admin'],
[Reza, 'editor'],
[Amir, 'subscriber'],
]);
for (let role of userRoles.values()) {
console.log(role);
}
خروجی این مثال از Map در جاوا اسکریپت به صورت زیر خواهد بود:
admin editor subscriber
مثال پیمایش عناصر Map
برای پیمایش عناصر Map در Javascript از متد entries()
استفاده میشود. این متد شیئی تکرارپذیر را بازمیگرداند که حاوی آرایهای از جفتهای کلید مقدار [key,value]
از هر عنصر در شی Map است.
در ادامه مثالی برای این نوع عملیات ارائه شده است.
let Ali= { name: 'Ali Ahmadi' },
Reza = { name: 'Reza Karimi' },
Amir = { name: 'Amir Mohammadi' };
let userRoles = new Map([
[Ali, 'admin'],
[reza, 'editor'],
[Amir, 'subscriber'],
]);
for (const role of userRoles.entries()) {
console.log(`${role[0].name}: ${role[1]}`);
}
به منظور اینکه روند تکرار یا پیمایش طبیعیتر شود، میتوان به صورت زیر از «تغییر ساختار» (Destructuring) استفاده کرد.
let Ali= { name: 'Ali Ahmadi' },
Reza= { name: 'Reza Karimi' },
Amir= { name: 'Amir Mohammadi' };
let userRoles = new Map([
[Ali, 'admin'],
[Reza, 'editor'],
[Amir, 'subscriber'],
]);
for (let [user, role] of userRoles.entries()) {
console.log(`${user.name}: ${role}`);
}
همچنین علاوه بر حلقه for…of
، میتوان از متد ForEach شی Map نیز به صورت زیر استفاده کرد.
let Ali= { name: 'Ali Ahmadi' },
Reza= { name: 'Reza Karimi' },
Amir= { name: 'Amir Mohammadi' };
let userRoles = new Map([
[Ali, 'admin'],
[Reza, 'editor'],
[Amir, 'subscriber'],
]);
userRoles.forEach((role, user) => console.log(`${user.name}: ${role}`));
مثال تبدیل کلید یا مقادیر Map به آرایه
خیلی از مواقع ممکن است بخواهیم به جای اینکه از شی تکرارپذیر استفاده کند، با آرایه کار خود را انجام دهیم. در چنین مواقعی میتوان از عملگر Spread استفاده کرد.
در مثال زیر کلیدهای هر عنصر به آرایهای از کلیدها تبدیل شدهاند.
var keys = [...userRoles.keys()];
console.log(keys);
خروجی این مثال به صورت زیر خواهد بود:
[ { name: 'Ali Ahmadi' }, { name: 'Reza Karimi' }, { name: 'Zahra Kazemi' } ]
همچنین قطعه کد زیر مقادیر مربوط به کلیدها را به آرایهای از عناصر تبدیل میکند.
let roles = [...userRoles.values()];
console.log(roles);
خروجی این مثال نیز به صورت زیر خواهد بود:
[ 'admin', 'editor', 'subscriber' ]
حذف عناصر Map با استفاده از کلید
برای حذف عناصر یا ورودیهای Map در جاوا اسکریپت از متدی به نام delete()
به صورت زیر استفاده میشود.
userRoles.delete(Ali);
با حذف Ali
از Map، اندازه Map به عدد ٢ کاهش خواهد یافت.
حذف تمامی عناصر Map در Javascript
براح حذف تمامی عناصر از متدی به نام clear()
به شیوه زیر استفاده میشود.
userRoles.clear();
حال اندازه Map با توجه به دستور clear()
صفر خواهد شد.
console.log(userRoles.size); // 0
همانطور که مشاهده شد، طول Map با این کار صفر خواهد شد.
WeakMap در جاوا اسکریپت چیست ؟
«WeakMap» در جاوا اسکریپت شبیه Map است، اما تفاوت آن با Map در این است که کلیدهای WeakMap باید از نوع شی باشند. این یعنی زمانی که ارجاع به کلید یا شی خارج از محدوده باشد، در نتیجه مقدار متناظر به صورت خودکار از حافظه آزاد خواهد شد.
WeakMap در جاوا اسکریپت فقط حاوی متدهای زیر مجموعه شی Map است که فهرست آنها به صورت موارد زیر خواهد بود:
- get(key)
- set(key, value)
- has(key)
- delete(key)
تفاوت بین WeekMap و Map در جاوا اسکریپت چیست ؟
با این اوصاف تفاوتهای عمده بین WeekMap و Map در Javascript به صورت زیر است.
- عناصر WeakMap تکرارپذیر نیستند.
- در WeekMap نمیتوان همه عناصر را یکجا پاک کرد.
- همچنین نمیتوان اندازه WeakMap را بررسی کرد.
چند سؤال متداول پیرامون Map در جاوا اسکریپت
در این بخش چند سؤال متداول و مهم پیرامون Map در جاوا اسکریپت پاسخ داده شدهاند.
کاربرد اصلی Map در Javascript چیست؟
به طور کلی، متد Map در زبان جاوا اسکریپت برای پیمایش آرایه و فراخوانی تابع بر روی هر عنصر آرایه به منظور تغییر یا دستکاری عناصر آن استفاده میشود.
Map بهتر است یا ForEach ؟
Map آرایه جدیدی را بازمیگرداند، در حالی که ForEach این کار را انجام نمیدهد. همچنین ForEach فقط روی مقدار در آرایه عمل میکند، اما Map قابلیت کار روی کلیدها را هم دارد.
مزیت Map در زبان برنامه نویسی جاوا اسکریپت چیست؟
با Map، انعطافپذیری بیشتری در کار با جفتهای کلید-مقدار وجود دارد، زیرا کلید میتواند هر مقداری مانند توابع، اشیا و غیره باشد. در شی، کلید فقط میتواند رشته یا نماد باشد. بسته به نحوه ذخیرهسازی دادههای خود، انعطافپذیری Map با انواع دادههای بیشتر، میتواند مفید باشد.
چرا به جای شی باید از Map استفاده کرد؟
Map قابل تکرار است، همچنین Map در مقایسه با شی کاربرد بهتری را برای نگاشت کلید-مقدار ارائه میدهد. تکرارپذیر بودن چندین مزیت دارد که اجرای به موقع یکی از آنها است.
سخن پایانی
مپ در زبان برنامه نویسی جاوا اسکریپت مجموعهای از جفتهای «کلید-مقدار» قابل پیمایش است. Map به کاربر امکان میدهد مجموعهای از مقادیر را به مجموعهای دیگر از مقادیر نگاشت کند و برای تبدیل دادهها به قالب و ساختمان دادهای مفیدتر، بسیار روش مناسبی است.
در این مطلب، سعی شد آموزش داده شود که چگونه با شی Map در جاوا اسکریپت کار کنیم و همچنین متدهای کاربردی آن برای کار روی ورودیها در Map معرفی شدند و مثالهایی برای هر یک ارائه شد. در آخر نیز WeakMap در زبان برنامه نویسی جاوا اسکریپت معرفی و تفاوت آن با Map شرح داده شد.