Avatar ·

كيف تجعل الإغلاقات في JavaScript تتذكر قيمة المتغير من التكرار الخاص بها؟

مرحباً بالجميع! أنا مبتدئ في JavaScript وواجهت مشكلة لا أفهمها تماماً. أكتب كوداً بسيطاً: أريد إضافة معالجات نقر لعدة أزرار، بحيث يطبع كل منها رقمه. هذا هو الكود الخاص بي: ```javascript const buttons = document.querySelectorAll('button'); for (var i = 0; i < buttons.length; i++) { buttons[i].addEventListener('click', function() { console.log('رقم الزر ' + i); }); } ``` لكن عندما أنقر على أي زر، تطبع console دائماً "رقم الزر 5" (آخر قيمة لـ i)، بغض النظر عن الزر الذي ضغطت عليه. قرأت أن هذا مرتبط بالإغلاقات، لكنني لا أفهم كيف أصلحه. لماذا يحدث هذا؟ كيف أجعل كل زر يتذكر رقمه؟ اشرح لي، من فضلك، بكلمات بسيطة مع أمثلة. شكراً مسبقاً! <<>>

لماذا تحدث المشكلة؟

المشكلة مرتبطة بكيفية عمل الإغلاقات ونطاق المتغير المُعلن باستخدام var. الكلمة المفتاحية var لا تنشئ نطاقاً على مستوى الكتلة (block scope)، بل على مستوى الدالة (function scope). في الحلقة for، المتغير i يُشارك عبر جميع التكرارات. عندما تُنشئ دالة (معالج النقر)، فإنها تُغلِق (closure) على المتغير i نفسه، وليس على قيمته في كل تكرار. لذلك، عندما يتم تنفيذ الدالة لاحقاً (عند النقر)، تكون قيمة i قد أصبحت القيمة النهائية بعد انتهاء الحلقة.