مراجعة كود JavaScript: أخطاء يكتشفها الخبراء وكيف تتجنبها

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مراجعة كود JavaScript: ما الذي يزعج الخبراء حقًا

\n\n

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

\n\n

لقد جمعنا أكثر التعليقات شيوعًا التي يتركها الخبراء أثناء مراجعة كود JavaScript. هذه ليست مجرد قائمة "هذا سيء وهذا جيد". إنها تحليل لماذا يعتبر نهج معين سيئًا وبماذا يمكن استبداله.

\n\n

هذه المقالة مفيدة لكل من يكتب بلغة JS: من المبتدئين إلى المطورين ذوي الخبرة الذين يرغبون في تحسين جودة كودهم.

\n\n

1. تغيير البيانات المدخلة: الخطيئة الكبرى

\n\n

من أكثر الأخطاء شيوعًا في مراجعة الكود هو تغيير الكائنات أو المصفوفات التي تم تمريرها إلى الدالة. يكره الخبراء هذا لأن التغيير يكسر مبدأ عدم القابلية للتغيير (immutability) ويؤدي إلى أخطاء يصعب تتبعها.

\n\n

مثال سيء

\n
function addUser(users, newUser) {\n  users.push(newUser); // تغيير المصفوفة الأصلية!\n  return users;\n}\n\nconst allUsers = [{ id: 1 }, { id: 2 }];\nconst updated = addUser(allUsers, { id: 3 });\nconsole.log(allUsers.length); // 3 — تم تغيير المصفوفة الأصلية!
\n\n

الطريقة الصحيحة

\n
function addUser(users, newUser) {\n  return [...users, newUser]; // إرجاع مصفوفة جديدة\n}\n\nconst allUsers = [{ id: 1 }, { id: 2 }];\nconst updated = addUser(allUsers, { id: 3 });\nconsole.log(allUsers.length); // 2 — الأصل لم يتغير
\n\n

لماذا هذا مهم: عندما تقوم بتغيير البيانات المدخلة، فإن أي كود آخر يشير إلى نفس الكائن سيتلقى تغييرات غير متوقعة. هذا طريق مباشر للأخطاء في العمليات غير المتزامنة (asynchronous)، مخازن Redux، وحالات React.

\n\n

2. الأرقام والنصوص السحرية: قاتلة readability

\n\n

غالبًا ما يكتب الخبراء في التعليقات: "ما هذا الرقم 86400؟" أو "من أين جاء هذا النص؟". القيم السحرية تجعل الكود غير مفهوم وتعقد صيانته.

\n\n

مثال سيء

\n
function calculateDiscount(price) {\n  if (price > 1000) {\n    return price * 0.9;\n  }\n  return price * 0.95;\n}
\n\n

الطريقة الصحيحة

\n
const DISCOUNT_THRESHOLD = 1000;\nconst HIGH_DISCOUNT_RATE = 0.9;\nconst STANDARD_DISCOUNT_RATE = 0.95;\n\nfunction calculateDiscount(price) {\n  if (price > DISCOUNT_THRESHOLD) {\n    return price * HIGH_DISCOUNT_RATE;\n  }\n  return price * STANDARD_DISCOUNT_RATE;\n}
\n\n

نصيحة: ضع جميع الثوابت في متغيرات مسماة أو ملف تكوين منفصل. هذا يبسط مراجعة كود JavaScript ويجعله موثقًا ذاتيًا.

\n\n

3. أخطاء async/await والـ Promises

\n\n

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

\n\n

مثال سيء (Promise بدون catch)

\n
async function loadData() {\n  const response = await fetch('/api/data');\n  const data = await response.json();\n  return data;\n}
\n\n

الطريقة الصحيحة

\n
async function loadData() {\n  try {\n    const response = await fetch('/api/data');\n    if (!response.ok) {\n      throw new Error(`خطأ HTTP! الحالة: ${response.status}`);\n    }\n    const data = await response.json();\n    return data;\n  } catch (error) {\n    console.error('خطأ في تحميل البيانات:', error);\n    throw error; // إعادة رمي الخطأ إذا لزم الأمر\n  }\n}
\n\n

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

\n\n

خطأ شائع آخر: نسيان await

\n
function processUsers(users) {\n  users.forEach(async (user) => {\n    await updateUser(user);

المدونات

توصيات الكتب