كيفية التكرار عبر المصفوفة في JavaScript: أهم الأخطاء وكيفية تجنبها
\n\nهل سبق لك أن كتبت كودًا كان من المفترض أن يمر ببساطة عبر قائمة من المهام أو المنتجات في سلة التسوق، ولكن بدلاً من ذلك أعاد undefined، أو حلقة لا نهائية، أو الأسوأ من ذلك، أفسد البيانات بهدوء؟ ألم مألوف. السؤال "How to loop through the items of an array in JavaScript?" هو أحد أكثر الأسئلة شيوعًا على Stack Overflow. يبدو الأمر بسيطًا، أليس كذلك؟ لكن الشيطان، كما هو الحال دائمًا، يكمن في التفاصيل.
اليوم لن نقوم فقط بتحليل كيفية التكرار عبر المصفوفة في JavaScript. سننظر تحت غطاء أكثر الأخطاء شيوعًا التي يقع فيها المبتدئون (وليس فقط). ستتعرف على لماذا يمكن أن يخذلك for...in، وكيف يختلف forEach عن map، وكيف تتجنب الوقوع في حلقة لا نهائية في for.
هل أنت مستعد؟ لنبدأ في إصلاح الأخطاء وكتابة كود جميل.
\n\nالخطأ رقم 1: استخدام for...in للمصفوفات
\n\nهذا، على الأرجح، أكثر الأخطاء شيوعًا بين المبتدئين. يرى المطور كلمة for وكلمة in ويفكر: "أوه، هذا للتكرار عبر كل شيء!". من الناحية الفنية، هذا صحيح. لكن بالنسبة للمصفوفات، هذا كارثة.
حلقة for...in مصممة للتكرار عبر خصائص الكائن، وليس عناصر المصفوفة. نعم، المصفوفة في JS هي أيضًا كائن، لكن فهارسها هي مجرد مفاتيح نصية ("0"، "1"، "2").
إليك المشكلة:
\n- \n
- الترتيب غير مضمون. على الرغم من أن المتصفحات عادةً ما تلتزم بالترتيب، إلا أنه لا يمكن الاعتماد على ذلك. \n
- يتكرر عبر كل الوراثة النموذجية. إذا قمت أنت أو أي مكتبة بإضافة طريقة إلى
Array.prototype(على سبيل المثال،Array.prototype.myCustomMethod = function() {})، فإنfor...inسيلتقطها أيضًا. \n
مثال كود (كيف لا تفعل):
\nconst arr = [10, 20, 30];\nArray.prototype.customMethod = () => {};\n\nfor (let index in arr) {\n console.log(arr[index]); // سيطبع: 10, 20, 30, ƒ () => {}\n}\n\n\nهل ترى؟ في النهاية ظهرت دالتنا المخصصة. الكود تعطل.
\n\nالطريقة الصحيحة:
\nاستخدم for...of (للقيم) أو for الكلاسيكي (للفهارس). for...of يتكرر فقط عبر القيم ويتجاهل النموذج الأولي.
// صحيح وآمن\nfor (let value of arr) {\n console.log(value); // 10, 20, 30\n}\n\n\nالخطأ رقم 2: نسيان رد النداء في forEach
\n\narr.forEach(callback) هي طريقة أنيقة للتكرار عبر المصفوفة في JavaScript. لكن الكثيرين يخلطون بينها وبين map أو filter. الخطأ الرئيسي هو الاعتقاد بأن forEach يُرجع شيئًا. إنه يُرجع undefined.
الخطأ الشائع الثاني هو نسيان الوسيطتين الثانية والثالثة لرد النداء (الفهرس والمصفوفة نفسها). أحيانًا يكون هذا حرجًا.
\n\nمثال على الخطأ:
\nconst numbers = [1, 2, 3];\nconst doubled = numbers.forEach(num => num * 2);\nconsole.log(doubled); // undefined! خطأ.\n\n\nالطريقة الصحيحة:
\nإذا كنت بحاجة إلى إنشاء مصفوفة جديدة بناءً على المصفوفة القديمة، استخدم map(). إذا كنت بحاجة فقط إلى تنفيذ إجراء (مثل الطباعة في وحدة التحكم أو إرسال البيانات)، استخدم forEach().
// لإنشاء مصفوفة جديدة\nconst doubled = numbers.map(num => num * 2); // [2, 4, 6]\n\n// للتأثيرات الجانبية\nnumbers.forEach((num, index) => {\n console.log(`العنصر ${index}: ${num}`);\n});\n\n\nالخطأ رقم 3: حلقة لا نهائية في for
\n\nكلاسيكي من النوع. تكتب for (let i = 0; i < arr.length; i++)، لكنك تنسى الزيادة i++ أو، الأسوأ من ذلك، تقوم بتعديل المصفوفة داخل الحلقة.
لنفترض أنك تقوم بتصفية المصفوفة أثناء التنقل، بإزالة العناصر باستخدام splice(). إذا لم تقم بتصحيح