المستوى: متوسط (Intermediate)
لو الـ dashboard بتاع التطبيق عندك بيستهلك 1.4GB RAM بعد ساعة شغل، و Chrome DevTools Heap Snapshot بيوريك كومة من الـ Detached DOM nodes، انت في 90% من الحالات قدام Memory Leak بسبب Map عادي بيمسك references لـ objects ما عادتش محتاجة. WeakMap بيحل الموضوع ده بسطرين كود، بدون أي تغيير في الـ business logic.
WeakMap و WeakSet: مرجع مش بيمنع الحذف
المشكلة باختصار
الـ Map العادي بيخزّن مرجع قوي (strong reference) لكل مفتاح بيدخل جواه. لو المفتاح ده object، الـ Garbage Collector مش بيقدر يحرر ذاكرته طول ما الـ Map موجود — حتى لو كل أماكن الكود التانية رمت الـ reference. ده مصدر شائع جدًا للـ Memory Leaks في تطبيقات React و Vue الكبيرة.
المثال البسيط: أوراق المكتبة
تخيّل إنك بتدير مكتبة فيها 50 ألف كتاب. كل كتاب فيه ورقة صغيرة عليها كود رف الكتاب. الورقة دي مش جزء من الكتاب — هي زيادة عليه. لو الكتاب اتباع وخرج من المكتبة، الورقة بقت بلا قيمة. المفروض ترميها.
دلوقتي تخيّل إنك مسكت قايمة منفصلة في الإدارة بصور كل ورقة منهم. مادمت ماسك القايمة دي، الأوراق مش هتترمي حتى لو الكتب نفسها رحلت. الإدارة هتفضل تشحن مساحة على بيانات بلا قيمة. ده اللي بيحصل بالظبط مع Map في JavaScript.
اللي بيحصل فعلًا في الكود
const userMetadata = new Map();
function attachMetadata(userObj) {
userMetadata.set(userObj, { lastSeen: Date.now() });
}
let user = { id: 42, name: "أحمد" };
attachMetadata(user);
// شغل تاني...
user = null; // المرجع الأصلي اتمسح
// لكن userMetadata لسه ماسك reference قوي للـ object
// النتيجة: V8 GC مش هيقدر يحرر الـ user object
// الذاكرة بتفضل محجوزة طول ما الـ Map موجود
ال Map بيخزّن المرجع بقوة. حتى لو كل الأماكن التانية في الكود رمت المرجع، الـ Map لسه ماسكه، فالـ GC مش هيلمسه. مع تطبيق فيه آلاف العمليات في الدقيقة، الـ heap بيكبر طول الوقت بدون ما يهبط.
التعريف الدقيق
طبقًا لـ ECMAScript 2024 Language Specification, Section 24.3:
- WeakMap: collection بتخزّن أزواج key-value، لكن الـ key بيتخزّن بـ weak reference. لما يبقى مفيش مرجع تاني للمفتاح في الكود، الـ GC بيحذف المفتاح والقيمة مع بعض تلقائيًا.
- المفتاح لازم يكون object (أو Symbol المسجّل في ES2023). string، number، boolean مش مقبولين.
- WeakMap مش قابل للتعداد: مفيش , , , , ولا .