أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

WeakMap بالعربي: اربط بيانات بالكائنات من غير Memory Leak

📅 ٢٤ أبريل ٢٠٢٦⏱ 4 دقائق قراءة
WeakMap بالعربي: اربط بيانات بالكائنات من غير Memory Leak

WeakMap بالعربي: اربط بيانات بالكائنات من غير Memory Leak

هتعرف هنا إمتى تستخدم WeakMap بدل Map عشان تربط بيانات مؤقتة بكائنات JavaScript من غير ما تعمل memory leak صامت يكبر مع الوقت.

المشكلة باختصار

الطريقة الشائعة إنك تعمل Map وتخزن فيها بيانات إضافية لكل object. مثال: آخر وقت request اتعمل، صلاحيات user داخل request، أو قياسات مؤقتة لكل DOM node. الطريقة دي بتفشل لما الكائن الأصلي يخلص شغله، لكن الـ Map تفضل ماسكة reference عليه. النتيجة: الـ garbage collector مش هيقدر يشيله من الذاكرة.

سيناريو واقعي: لو عندك لوحة تحكم بتفتح وتقفل 20,000 row يوميًا، وكل row مربوط ببيانات UI داخل Map، ممكن تفضل البيانات القديمة عايشة لساعات. لو كل row ماسك 2KB metadata، فأنت بتتكلم عن حوالي 40MB زيادة في اليوم من غير سبب واضح.

خوادم وشاشات مراقبة تمثل تتبع استهلاك الذاكرة في تطبيق JavaScript

الفكرة بمثال بسيط

ركز في المثال ده. عندك موظف داخل شركة، ومعاه كارت دخول مؤقت. لما الموظف يسيب الشركة، المفروض الكارت يتلغي تلقائيًا. Map هنا عاملة زي مكتب أمن بيحتفظ بصورة الموظف والكارت حتى بعد ما الموظف مشي. WeakMap أقرب لنظام بيقول: طالما الموظف نفسه مش موجود في أي مكان تاني، امسح بيانات الكارت معاه.

علميًا، WeakMap لا تعمل strong reference على المفاتيح. المفتاح لازم يكون object أو non-registered symbol. لو الكائن لم يعد reachable من باقي البرنامج، وجوده كمفتاح داخل WeakMap لا يمنع جمعه بواسطة الـ garbage collector. ده موثق في MDN، وده سبب إن WeakMap لا تسمح بعمل loop على المفاتيح: لأن حالة المفاتيح مرتبطة بالـ garbage collection، وهي عملية غير حتمية.

مثال تنفيذي يقيس الفرق

الافتراض إنك بتشغل Node.js محليًا، وعايز تشوف الفرق بشكل تقريبي. القياس مش benchmark نهائي، لأن الـ garbage collector توقيته مش مضمون. لكنه كفاية يوضح السلوك.

شاشة كود JavaScript توضح مثال ربط بيانات مؤقتة بالكائنات
JavaScript
// weakmap-demo.js
// شغله كده:
// node --expose-gc weakmap-demo.js map
// node --expose-gc weakmap-demo.js weak

const mode = process.argv[2] || "map";
const store = mode === "weak" ? new WeakMap() : new Map();

function mb() {
  return Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
}

if (!global.gc) {
  throw new Error("Run with: node --expose-gc weakmap-demo.js map|weak");
}

global.gc();
console.log("before", mb(), "MB");

for (let i = 0; i < 50_000; i++) {
  const request = { id: i };
  store.set(request, {
    startedAt: Date.now(),
    payload: "x".repeat(2048)
  });
}

global.gc();
console.log("after", mb(), "MB");
console.log("mode", mode, "size", store.size ?? "not enumerable");

على جهاز متوسط، نسخة map ممكن تفضل ماسكة عشرات الميجابايت لأن store.size يساوي 50,000. نسخة weak لا تقدر تعرض size، وده مقصود. بعد الـ GC، الكائنات التي لم يعد لها references خارجية تصبح قابلة للإزالة. الرقم المتوقع هنا تقريبي: فرق 30MB إلى 90MB حسب نسخة Node وطريقة تخصيص الذاكرة.

إمتى WeakMap هي أفضل طريقة

استخدم WeakMap لما تكون البيانات تابعة لعمر object آخر. أمثلة واضحة: metadata لكل request في middleware، cache مشتق من DOM node، private data داخل class، أو ربط حالة مؤقتة بكائن من مكتبة خارجية لا تريد تعديله مباشرة.

  • بتكسب: تقليل خطر تسريب الذاكرة لما الكائن الأصلي يختفي.
  • بتخسر: لا يوجد size، ولا keys()، ولا iteration على المحتوى.
  • بتكسب: عدم تلويث الكائن الأصلي بخصائص إضافية مثل __meta.
  • بتخسر: صعوبة أعلى في debugging لأنك لا ترى كل المفاتيح بسهولة.

الـ trade-off هنا واضح: WeakMap ممتازة لعلاقة "بيانات تابعة لكائن"، لكنها سيئة لو محتاج تعدّ العناصر أو تطبع كل المفاتيح في تقرير.

متى لا تستخدم هذه الطريقة

لا تستخدم WeakMap لو محتاج cache قابل للفحص، أو لازم تعمل eviction بسياسة واضحة مثل LRU، أو محتاج تعرف عدد العناصر بدقة. في الحالات دي استخدم Map مع TTL أو مكتبة cache واضحة. كمان لا تستخدمها لو المفاتيح عندك strings أو numbers؛ WeakMap لا تقبل primitive keys.

لو عايز cache لنتائج API حسب userId، فـ Map أو Redis أنسب. أما لو عايز metadata مؤقتة لكائن request نفسه، WeakMap أنظف.

مصادر اعتمدت عليها

  • MDN: WeakMap لتعريف weak references وقيود المفاتيح وعدم قابلية التعداد.
  • Node.js: process.memoryUsage لقراءة استهلاك heap في المثال.
  • Chrome DevTools: Heap snapshots لفهم مقارنة snapshots وتتبع retained objects.

الخطوة التالية

افتح أي مكان في مشروعك بيستخدم Map ومفتاحه object. لو البيانات مرتبطة بعمر المفتاح فقط، جرّب تحويله إلى WeakMap وشغّل heap snapshot قبل وبعد 1000 عملية فتح وإغلاق.

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة