محتويات الدورة

JavaScript / أساسي: القيم وأسس المتصفح / الدرس 4

الإغلاقات والحالة الخاصة

تتبع عمر الارتباطات المعجمية وابنِ دوال ذات حالة مستقلة. تكشف العدادات واستدعاءات الحلقات واللقطات ما يحتفظ به الإغلاق ومتى يقرأه.

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • شرح الارتباطات الملتقطة والاستدعاءات المستقلة.
  • تمييز الارتباط الحي من اللقطة.
  • إدارة ملكية الحالة المحتفظ بها وعمرها.

تحتفظ الدالة المعادة بإمكان الوصول

يجمع الإغلاق دالة وإمكان الوصول لبيئتها المعجمية المحيطة. لا يرمي إرجاع الدالة الارتباطات التي تحتاجها. تنشئ كل دعوة للمصنع بيئة استدعاء مختلفة، فيحفظ عدادان مجموعين مستقلين. لا تنسخ الحالة في كل استدعاء للدالة المعادة؛ بل يرى اللاحق التعديلات في الارتباط الملتقط نفسه. يفيد ذلك التغليف، لكنه يعني أن الاستدعاء الراجع قد يلاحظ قيمة أحدث من قيمة التسجيل. حدّد البيئة المالكة لكل ارتباط.

javascript بيئات مستقلة من المصنع نفسه
function makeCounter() {
  let count = 0;
  return () => ++count;
}
const a = makeCounter();
const b = makeCounter();
console.log(a(), a(), b(), a());
الناتج المتوقع
1 2 1 3

تحتفظ a بارتباط count وتحتفظ b بآخر. تحدث دعوات a ارتباطها القائم.

اختيار الملاحظة الحية أو اللقطة

قرر هل تصف رسالة التأكيد قيمة وقت الجدولة أم أحدث قيمة عند العرض. يوفر التقاط ارتباط متغير وصولاً حياً، ويحفظ تخزين قيمة أولية في const جديد تلك القيمة. تحتاج لقطة الكائن نسخاً مناسباً لأن مرجع const قد يصل لخصائص متغيرة. يهم ذلك في الحفظ المؤجل والملخصات؛ فقد يربط رصد أحدث مسودة بصمت تسمية خاطئة بفعل سابق. اجعل وقت الملاحظة المقصود جزءاً من عقد الدالة.

تؤثر ارتباطات الحلقة في الاستدعاءات اللاحقة

يوفر let في رأس for ارتباطات لكل دورة في سلوك الإغلاق المعني. أما var فبنطاق الدالة، وقد ترى جميع الاستدعاءات قيمته النهائية بعد الحلقة. افهم عمر الارتباط بدلاً من إضافة مهلات أو أغلفة عشوائية. لا يحتاج المثال مؤقتاً؛ نخزن الدوال ونستدعيها بعد المرور لنجعل الالتقاط حتمياً. طبّق الفهم على أزرار قائمة؛ إذ يحتاج كل معالج معرف عنصره لا فهرساً مشتركاً تقدم بالفعل.

javascript حالة لكل دورة وارتباط خارجي حي
const handlers = [];
for (let i = 0; i < 3; i++) handlers.push(() => i);
console.log(handlers.map(fn => fn()).join(","));
let label = "draft";
const read = () => label;
label = "saved";
console.log(read());
الناتج المتوقع
0,1,2
saved

تحفظ الدوال الثلاث ارتباطات i مختلفة. وتصل read إلى label فتعيد قيمته اللاحقة.

إتاحة العمليات لا التعديل الاعتباطي

يمكن لمصنع حجز إخفاء العدد وإتاحة عمليتي الحجز والتوفر اللتين تحفظان ثابت السعة. لا يعيد المستدعي إسناد الارتباط المعجمي مباشرة، لكن إعادة الكائن الداخلي المتغير تسمح بتجاوز العمليات. يشمل التغليف قرارات المراجع المعادة؛ فقد تعيد القراءة قيمة أولية أو لقطة مقصودة بدلاً من مجموعة حية. الإغلاقات أداة بجانب الحقول الخاصة والوحدات. اختر تمثيلاً يجعل الانتقالات قابلة للمراجعة ولا تعتبر الإخفاء صحة تلقائية.

قد يعيش الإغلاق بعد واجهته

قد يبقي مستمع أو مؤقت أو مخبأ الإغلاق قابلاً للوصول، فيحتفظ بدوره بجزء مستند أو مصفوفة كبيرة. لا يجمع المحرك كائنات تبقى قابلة للوصول عبر هذه المسارات. عند إزالة مكوّن حرر التسجيلات والمراجع التي يملكها ولا تعتمد على توقيت جمع معين. تجعل عملية dispose صريحة دورة الحياة قابلة للاختبار. تجنب التقاط استجابة كاملة إذا كفى معرف ثابت. يعود تشخيص الذاكرة لاحقاً للسؤال نفسه: أي مالك قابل للوصول ما زال يحتاج الحالة؟

الأخطاء الشائعة وإصلاحها

استخدام كل استدعاء للعنصر الأخير

لماذا يحدث؟
اشتراكها في ارتباط متغير بنطاق الدالة.
كيف تصلحه؟
استخدام let لكل دورة أو تمرير عنصر ثابت.
كيف تتجنب تكراره؟
تشغيل المعالجات المخزنة في اختبار حتمي.

تغير لقطة مفترضة لاحقاً

لماذا يحدث؟
احتفاظ الإغلاق بارتباط حي أو كائن مشترك.
كيف تصلحه؟
التقاط القيمة الأولية أو نسخ الحقول اللازمة.
كيف تتجنب تكراره؟
تحديد وقت الملاحظة: الإنشاء أم الاستدعاء.

احتفاظ عرض محذوف ببيانات كبيرة

لماذا يحدث؟
بقاء تسجيل طويل العمر يشير للإغلاق.
كيف تصلحه؟
إزالة التسجيلات المملوكة والمراجع غير الضرورية.
كيف تتجنب تكراره؟
ربط الإعداد بمسار تحرير صريح.

اختبر فهمك

1. توقع سلوك مصنعين يعيد كل منهما عداداً يبدأ بعشرة.

اعرض الحل المشروح

لكل دعوة مصنع ارتباط مستقل. إذا زادت الدالة قبل الإرجاع فإن a() وa() وb() تعطي 11 و12 و11. لا يعني النص المشترك حالة استدعاء مشتركة؛ وينتج ارتباط عام للوحدة تصميماً آخر.

2. يجب أن يحتفظ إيصال مؤجل بالمبلغ المسلم لا المعدل. ماذا يلتقط؟

اعرض الحل المشروح

أنشئ ارتباطاً جديداً للمبلغ العددي المتحقق منه والتقطه للإيصال. لا تقرأ النموذج أو المسودة المتغيرة لاحقاً. وللبيانات المتداخلة انسخ الحقول المطلوبة فقط بسياسة لقطة صريحة.

أهم ما تعلمته

  • تحتفظ الإغلاقات بالوصول للارتباطات لا تاريخ مجمد تلقائياً.
  • تحتاج خصوصية الحالة وعمرها ملكية مقصودة.

المراجع الرسمية