JavaScript WeakMap va WeakSet: xotira boshqaruvi uchun kuchli vositalar. Xotira sizishini qanday oldini olishi va ilovalarni optimallashtirishini amaliy misollar bilan o'rganing.
JavaScript'da xotira boshqaruvi uchun WeakMap va WeakSet: Keng qamrovli qo'llanma
Xotira boshqaruvi mustahkam va yuqori samarali JavaScript ilovalarini yaratishning muhim jihatidir. An'anaviy ma'lumotlar tuzilmalari, masalan, Objects
va Arrays
, ba'zida, ayniqsa obyekt havolalari bilan ishlashda, xotira sizishiga olib kelishi mumkin. Yaxshiyamki, JavaScript ushbu muammolarni hal qilish uchun mo'ljallangan ikkita kuchli vosita – WeakMap
va WeakSet
'ni taqdim etadi. Ushbu keng qamrovli qo'llanma WeakMap
va WeakSet
'ning nozik jihatlariga chuqur kirib boradi, ularning qanday ishlashini, afzalliklarini tushuntiradi va loyihalaringizda ulardan samarali foydalanishga yordam beradigan amaliy misollar beradi.
JavaScript'da xotira sizishini tushunish
WeakMap
va WeakSet
'ga sho'ng'ishdan oldin, ular hal qiladigan muammoni — xotira sizishini tushunish muhimdir. Xotira sizishi ilovangiz xotirani ajratib, lekin unga ehtiyoj qolmaganida ham uni tizimga qaytara olmaganda sodir bo'ladi. Vaqt o'tishi bilan bu sizishlar to'planib, ilovangizni sekinlashtirishi va oxir-oqibat ishlamay qolishiga olib kelishi mumkin.
JavaScript'da xotira boshqaruvi asosan axlat yig'uvchi tomonidan avtomatik ravishda boshqariladi. Axlat yig'uvchi vaqti-vaqti bilan ildiz obyektlaridan (global obyekt, chaqiruv staki va boshqalar) erishib bo'lmaydigan obyektlar egallagan xotirani aniqlaydi va qaytaradi. Biroq, ko'zda tutilmagan obyekt havolalari axlat yig'ishning oldini olib, xotira sizishiga olib kelishi mumkin. Keling, oddiy misolni ko'rib chiqaylik:
let element = document.getElementById('myElement');
let data = {
element: element,
value: 'Some data'
};
// ... keyinroq
// Element DOM'dan olib tashlangan bo'lsa ham, 'data' hali ham unga havola saqlaydi.
// Bu elementning axlat yig'uvchi tomonidan tozalanishiga to'sqinlik qiladi.
Ushbu misolda, data
obyekti DOM elementi element
ga havola saqlaydi. Agar element
DOM'dan olib tashlansa, lekin data
obyekti hali ham mavjud bo'lsa, axlat yig'uvchi element
egallagan xotirani qaytara olmaydi, chunki u hali ham data
orqali erishib bo'ladi. Bu veb-ilovalarida xotira sizishining keng tarqalgan manbaidir.
WeakMap'ni tanishtirish
WeakMap
kalit-qiymat juftliklarining to'plami bo'lib, bunda kalitlar obyektlar bo'lishi shart, qiymatlar esa ixtiyoriy bo'lishi mumkin. "Zaif" atamasi WeakMap
'dagi kalitlar zaif holda saqlanishini anglatadi, ya'ni ular axlat yig'uvchining ushbu kalitlar egallagan xotirani qaytarishiga to'sqinlik qilmaydi. Agar kalit obyekti kodingizning boshqa qismidan erishib bo'lmaydigan bo'lsa va u faqat WeakMap
tomonidan havola qilingan bo'lsa, axlat yig'uvchi ushbu obyektning xotirasini bemalol qaytarishi mumkin. Kalit axlat yig'uvchi tomonidan tozalanilganda, WeakMap
'dagi mos keladigan qiymat ham axlat yig'ish uchun mos bo'ladi.
WeakMap'ning asosiy xususiyatlari:
- Kalitlar obyekt bo'lishi kerak: Faqat obyektlar
WeakMap
'da kalit sifatida ishlatilishi mumkin. Raqamlar, satrlar yoki mantiqiy qiymatlar kabi primitiv qiymatlarga ruxsat berilmaydi. - Zaif havolalar: Kalitlar zaif holda saqlanadi, bu kalit obyekti boshqa joydan erishib bo'lmaydigan bo'lganda axlat yig'ishga imkon beradi.
- Iteratsiya yo'q:
WeakMap
o'z kalitlari yoki qiymatlari bo'yicha iteratsiya qilish uchun usullarni (masalan,forEach
,keys
,values
) taqdim etmaydi. Buning sababi shundaki, bu usullarning mavjudligiWeakMap
'dan kalitlarga kuchli havolalarni saqlashni talab qiladi, bu esa zaif havolalar maqsadiga zid keladi. - Shaxsiy ma'lumotlarni saqlash:
WeakMap
ko'pincha obyektlar bilan bog'liq shaxsiy ma'lumotlarni saqlash uchun ishlatiladi, chunki ma'lumotlarga faqat obyektning o'zi orqali kirish mumkin.
WeakMap'dan asosiy foydalanish:
WeakMap
'dan qanday foydalanish haqida oddiy misol:
let weakMap = new WeakMap();
let element = document.getElementById('myElement');
weakMap.set(element, 'Element bilan bog\'liq ma\'lumotlar');
console.log(weakMap.get(element)); // Chiqish: Element bilan bog'liq ma'lumotlar
// Agar element DOM'dan olib tashlansa va boshqa joyda havolasi bo'lmasa,
// axlat yig'uvchi uning xotirasini qaytarishi mumkin va WeakMap'dagi yozuv ham o'chiriladi.
Amaliy misol: DOM element ma'lumotlarini saqlash
WeakMap
uchun keng tarqalgan foydalanish holatlaridan biri DOM elementlari bilan bog'liq ma'lumotlarni, ularning axlat yig'ilmasligiga to'sqinlik qilmasdan saqlashdir. Veb-sahifadagi har bir tugma uchun ba'zi metama'lumotlarni saqlashni istagan ssenariyni ko'rib chiqing:
let buttonMetadata = new WeakMap();
let button1 = document.getElementById('button1');
let button2 = document.getElementById('button2');
buttonMetadata.set(button1, { clicks: 0, label: 'Tugma 1' });
buttonMetadata.set(button2, { clicks: 0, label: 'Tugma 2' });
button1.addEventListener('click', () => {
let data = buttonMetadata.get(button1);
data.clicks++;
console.log(`Tugma 1 clicked ${data.clicks} times`);
});
// Agar button1 DOM'dan olib tashlansa va boshqa joyda havolasi bo'lmasa,
// axlat yig'uvchi uning xotirasini qaytarishi mumkin va buttonMetadata'dagi mos keladigan yozuv ham o'chiriladi.
Ushbu misolda, buttonMetadata
har bir tugma uchun bosishlar soni va yorlig'ini saqlaydi. Agar tugma DOM'dan olib tashlansa va boshqa joyda havolasi bo'lmasa, axlat yig'uvchi uning xotirasini qaytarishi mumkin va buttonMetadata
'dagi mos keladigan yozuv avtomatik ravishda o'chiriladi, bu esa xotira sizishining oldini oladi.
Xalqaro (Internationalization) mulohazalar
Bir nechta tillarni qo'llab-quvvatlaydigan foydalanuvchi interfeyslari bilan ishlashda, WeakMap
ayniqsa foydali bo'lishi mumkin. Siz DOM elementlari bilan bog'liq lokalga xos ma'lumotlarni saqlashingiz mumkin:
let localizedStrings = new WeakMap();
let heading = document.getElementById('heading');
// Inglizcha versiya
localizedStrings.set(heading, {
en: 'Veb-saytimizga xush kelibsiz!',
fr: 'Bienvenue sur notre site web!',
es: '¡Bienvenido a nuestro sitio web!'
});
function updateHeading(locale) {
let strings = localizedStrings.get(heading);
heading.textContent = strings[locale];
}
updateHeading('fr'); // Sarlavhani fransuz tiliga o'zgartiradi
Ushbu yondashuv sizga lokalizatsiya qilingan satrlarni DOM elementlari bilan, axlat yig'ishning oldini oladigan kuchli havolalarni saqlamasdan bog'lash imkonini beradi. Agar heading
elementi olib tashlansa, localizedStrings
'dagi bog'liq lokalizatsiya qilingan satrlar ham axlat yig'ish uchun mos bo'ladi.
WeakSet'ni tanishtirish
WeakSet
WeakMap
'ga o'xshaydi, lekin u kalit-qiymat juftliklari emas, balki obyektlar to'plamidir. WeakMap
kabi, WeakSet
ham obyektlarni zaif holda saqlaydi, ya'ni u axlat yig'uvchining ushbu obyektlar egallagan xotirani qaytarishiga to'sqinlik qilmaydi. Agar obyekt kodingizning boshqa qismidan erishib bo'lmaydigan bo'lsa va u faqat WeakSet
tomonidan havola qilingan bo'lsa, axlat yig'uvchi ushbu obyektning xotirasini bemalol qaytarishi mumkin.
WeakSet'ning asosiy xususiyatlari:
- Qiymatlar obyekt bo'lishi kerak: Faqat obyektlar
WeakSet
'ga qo'shilishi mumkin. Primitiv qiymatlarga ruxsat berilmaydi. - Zaif havolalar: Obyektlar zaif holda saqlanadi, bu obyekt boshqa joydan erishib bo'lmaydigan bo'lganda axlat yig'ishga imkon beradi.
- Iteratsiya yo'q:
WeakSet
o'z elementlari bo'yicha iteratsiya qilish uchun usullarni (masalan,forEach
,values
) taqdim etmaydi. Buning sababi shundaki, iteratsiya qilish kuchli havolalarni talab qiladi, bu esa maqsadga zid keladi. - A'zolikni kuzatish:
WeakSet
ko'pincha obyektning ma'lum bir guruh yoki kategoriyaga tegishli ekanligini kuzatish uchun ishlatiladi.
WeakSet'dan asosiy foydalanish:
WeakSet
'dan qanday foydalanish haqida oddiy misol:
let weakSet = new WeakSet();
let element1 = document.getElementById('element1');
let element2 = document.getElementById('element2');
weakSet.add(element1);
weakSet.add(element2);
console.log(weakSet.has(element1)); // Chiqish: true
console.log(weakSet.has(element2)); // Chiqish: true
// Agar element1 DOM'dan olib tashlansa va boshqa joyda havolasi bo'lmasa,
// axlat yig'uvchi uning xotirasini qaytarishi mumkin va u WeakSet'dan avtomatik ravishda o'chiriladi.
Amaliy misol: Faol foydalanuvchilarni kuzatish
WeakSet
uchun foydalanish holatlaridan biri veb-ilovada faol foydalanuvchilarni kuzatishdir. Foydalanuvchi obyektlarini ilovadan faol foydalanganda WeakSet
'ga qo'shishingiz va ular nofaol bo'lganda olib tashlashingiz mumkin. Bu sizga faol foydalanuvchilarni ularning axlat yig'ilishiga to'sqinlik qilmasdan kuzatish imkonini beradi.
let activeUsers = new WeakSet();
function userLoggedIn(user) {
activeUsers.add(user);
console.log(`Foydalanuvchi ${user.id} tizimga kirdi. Faol foydalanuvchilar: ${activeUsers.has(user)}`);
}
function userLoggedOut(user) {
// WeakSet'dan aniq o'chirishga hojat yo'q. Agar foydalanuvchi obyekti boshqa havolaga ega bo'lmasa,
// u axlat yig'iladi va WeakSet'dan avtomatik ravishda olib tashlanadi.
console.log(`Foydalanuvchi ${user.id} tizimdan chiqdi.`);
}
let user1 = { id: 1, name: 'Alice' };
let user2 = { id: 2, name: 'Bob' };
userLoggedIn(user1);
userLoggedIn(user2);
userLoggedOut(user1);
// Bir muncha vaqt o'tgach, agar user1 boshqa joyda havolaga ega bo'lmasa, u axlat yig'iladi
// va avtomatik ravishda activeUsers WeakSet'idan olib tashlanadi.
Foydalanuvchilarni kuzatish bo'yicha xalqaro mulohazalar
Turli mintaqalardagi foydalanuvchilar bilan ishlashda, foydalanuvchi preferensiyalarini (til, valyuta, vaqt zonasi) foydalanuvchi obyektlari bilan birga saqlash keng tarqalgan amaliyot bo'lishi mumkin. WeakMap
ni WeakSet
bilan birgalikda ishlatish foydalanuvchi ma'lumotlari va faol holatini samarali boshqarish imkonini beradi:
let activeUsers = new WeakSet();
let userPreferences = new WeakMap();
function userLoggedIn(user, preferences) {
activeUsers.add(user);
userPreferences.set(user, preferences);
console.log(`Foydalanuvchi ${user.id} quyidagi preferensiyalar bilan tizimga kirdi:`, userPreferences.get(user));
}
let user1 = { id: 1, name: 'Alice' };
let user1Preferences = { language: 'en', currency: 'USD', timeZone: 'America/Los_Angeles' };
userLoggedIn(user1, user1Preferences);
Bu foydalanuvchi preferensiyalari faqat foydalanuvchi obyekti mavjud bo'lsa saqlanishini ta'minlaydi va foydalanuvchi obyekti axlat yig'ilsa, xotira sizishining oldini oladi.
WeakMap va Map, WeakSet va Set: Asosiy farqlar
WeakMap
va Map
, shuningdek WeakSet
va Set
o'rtasidagi asosiy farqlarni tushunish muhimdir:
Xususiyat | WeakMap |
Map |
WeakSet |
Set |
---|---|---|---|---|
Kalit/Qiymat turi | Faqat obyektlar (kalitlar), har qanday qiymat (qiymatlar) | Har qanday tur (kalitlar va qiymatlar) | Faqat obyektlar | Har qanday tur |
Havola turi | Zaif (kalitlar) | Kuchli | Zaif | Kuchli |
Iteratsiya | Ruxsat etilmaydi | Ruxsat etiladi (forEach , keys , values ) |
Ruxsat etilmaydi | Ruxsat etiladi (forEach , values ) |
Axlat yig'ish | Agar boshqa kuchli havolalar mavjud bo'lmasa, kalitlar axlat yig'ishga mos keladi | Map mavjud ekan, kalitlar va qiymatlar axlat yig'ishga mos kelmaydi | Agar boshqa kuchli havolalar mavjud bo'lmasa, obyektlar axlat yig'ishga mos keladi | Set mavjud ekan, obyektlar axlat yig'ishga mos kelmaydi |
WeakMap va WeakSet'dan qachon foydalanish kerak
WeakMap
va WeakSet
quyidagi ssenariylarda ayniqsa foydalidir:
- Ma'lumotlarni obyektlar bilan bog'lash: Obyektlar (masalan, DOM elementlari, foydalanuvchi obyektlari) bilan bog'liq ma'lumotlarni, ularning axlat yig'ilishiga to'sqinlik qilmasdan saqlashingiz kerak bo'lganda.
- Shaxsiy ma'lumotlarni saqlash: Faqat obyektning o'zi orqali kirish mumkin bo'lgan obyektlar bilan bog'liq shaxsiy ma'lumotlarni saqlashni istaganingizda.
- Obyekt a'zoligini kuzatish: Obyektning ma'lum bir guruh yoki kategoriyaga tegishli ekanligini, uning axlat yig'ilishiga to'sqinlik qilmasdan kuzatishingiz kerak bo'lganda.
- Qimmat operatsiyalarni keshlash: Obyektlarda bajarilgan qimmat operatsiyalar natijalarini keshlash uchun
WeakMap
'dan foydalanishingiz mumkin. Agar obyekt axlat yig'ilsa, keshdagi natija ham avtomatik ravishda tashlab yuboriladi.
WeakMap va WeakSet'dan foydalanish bo'yicha eng yaxshi amaliyotlar
- Obyektlarni kalit/qiymat sifatida ishlating: Esda tutingki,
WeakMap
vaWeakSet
faqat obyektlarni mos ravishda kalit yoki qiymat sifatida saqlay oladi. - Kalit/qiymatlarga kuchli havolalardan saqlaning:
WeakMap
yokiWeakSet
'da saqlangan kalitlar yoki qiymatlarga kuchli havolalar yaratmasligingizga ishonch hosil qiling, chunki bu zaif havolalar maqsadini buzadi. - Muqobillarni ko'rib chiqing:
WeakMap
yokiWeakSet
sizning maxsus foydalanish holatingiz uchun to'g'ri tanlov ekanligini baholang. Ba'zi hollarda, odatiyMap
yokiSet
mosroq bo'lishi mumkin, ayniqsa agar siz kalitlar yoki qiymatlar bo'yicha iteratsiya qilishingiz kerak bo'lsa. - Puxta sinovdan o'tkazing: Xotira sizishini yaratmasligingizga va
WeakMap
vaWeakSet
'ingiz kutilganidek ishlashiga ishonch hosil qilish uchun kodingizni puxta sinovdan o'tkazing.
Brauzer mosligi
WeakMap
va WeakSet
barcha zamonaviy brauzerlar tomonidan qo'llab-quvvatlanadi, jumladan:
- Google Chrome
- Mozilla Firefox
- Safari
- Microsoft Edge
- Opera
WeakMap
va WeakSet
'ni o'z ichiga olmaydigan eski brauzerlar uchun funksionallikni ta'minlash uchun polifillardan foydalanishingiz mumkin.
Xulosa
WeakMap
va WeakSet
JavaScript ilovalarida xotirani samarali boshqarish uchun qimmatli vositalardir. Ularning qanday ishlashini va qachon foydalanishni tushunib, siz xotira sizishining oldini olishingiz, ilovangizning ishlashini optimallashtirishingiz hamda mustahkam va qo'llab-quvvatlanadigan kod yozishingiz mumkin. WeakMap
va WeakSet
'ning cheklovlarini, masalan, kalitlar yoki qiymatlar bo'yicha iteratsiya qila olmaslikni yodda tuting va o'zingizning maxsus foydalanish holatingiz uchun mos ma'lumotlar tuzilmasini tanlang. Ushbu eng yaxshi amaliyotlarni qo'llash orqali siz WeakMap
va WeakSet
kuchidan foydalanib, global miqyosda ishlaydigan yuqori samarali JavaScript ilovalarini yaratishingiz mumkin.