كيف تعمل علامة الاستفهام (?) في JavaScript؟ شرح المعامل الثلاثي وOptional Chaining وNullish Coalescing

دقائق القراءة: 5

مقدمة: لماذا تُعد علامة ? من أقوى الرموز في JavaScript؟

تبدو علامة ? بسيطة للوهلة الأولى، لكنها في الواقع من أكثر الأدوات مرونة وفائدة في لغة JavaScript. فهي لا تُستخدم فقط لاختصار الشروط، بل تدخل أيضاً في ميزات حديثة تساعد على كتابة كود أكثر أماناً ووضوحاً، خاصة عند التعامل مع القيم المفقودة أو البيانات القادمة من API أو قواعد البيانات.

في هذا المقال سنشرح الاستخدامات الثلاثة الأهم لعلامة ? في JavaScript بأسلوب عملي ومبسط:

  • المعامل الثلاثي Ternary Operator
  • السلسلة الاختيارية Optional Chaining
  • دمج القيم الفارغة Nullish Coalescing

شرح استخدامات علامة الاستفهام في جافاسكربت بما يشمل المعامل الثلاثي والسلسلة الاختيارية ودمج القيم الفارغة

أولاً: المعامل الثلاثي Ternary Operator

مصطلح Ternary يعني أن العملية تعتمد على ثلاثة أجزاء. ولهذا سُمّي هذا المعامل بالمعامل الثلاثي، لأنه الوحيد تقريباً في الاستخدام الشائع داخل JavaScript الذي يستقبل ثلاثة عناصر:

  1. شرط
  2. قيمة تُعاد إذا كان الشرط صحيحاً
  3. قيمة تُعاد إذا كان الشرط خاطئاً

الصيغة العامة تكون كالتالي:

condition ? valueIfTrue : valueIfFalse

بمعنى آخر، نكتب الشرط أولاً، ثم نضع ?، ثم القيمة التي ستُعاد عند تحقق الشرط، وبعدها : ثم القيمة البديلة إذا لم يتحقق الشرط.

صيغة المعامل الثلاثي في جافاسكربت باستخدام علامة الاستفهام والنقطتين

متى نستخدم المعامل الثلاثي؟

يُستخدم هذا الأسلوب عندما تحتاج إلى شرط بسيط وتريد كتابة الكود بشكل مختصر وواضح بدلاً من استخدام جملة if...else الكاملة.

مقارنة بين Ternary Operator وif...else

المعامل الثلاثي يُعد اختصاراً أنيقاً لعبارة if...else. ففي كثير من الحالات، يمكن كتابة نفس المنطق في سطر واحد بدلاً من عدة أسطر.

مقارنة بين المعامل الثلاثي وجملة if else في جافاسكربت

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

مزايا المعامل الثلاثي

  • تقليل عدد الأسطر البرمجية
  • جعل الشروط البسيطة أكثر اختصاراً
  • مناسب داخل عمليات الإسناد أو return

ثانياً: السلسلة الاختيارية Optional Chaining

في الإصدارات الحديثة من JavaScript ظهرت ميزة ممتازة تُعرف باسم Optional Chaining. هذه الميزة تحل مشكلة شائعة جداً عند الوصول إلى خصائص كائن قد لا تكون موجودة.

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

مثال على الوصول إلى خاصية غير موجودة في كائن داخل جافاسكربترسالة الخطأ TypeError عند محاولة قراءة خاصية من قيمة undefined في جافاسكربت

ومن أشهر الرسائل التي قد تراها: TypeError: Cannot read property 'salary' of undefined.

كيف تعمل Optional Chaining؟

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

استخدام Optional Chaining في جافاسكربت لتفادي أخطاء الوصول إلى الخصائص غير الموجودة

هذا السلوك مفيد جداً عند التعامل مع كائنات متداخلة، مثل بيانات المستخدمين أو الردود القادمة من واجهات البرمجة، لأنه يقلل الحاجة إلى كتابة فحوصات متكررة قبل كل مستوى من الخصائص.

فوائد Optional Chaining

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

ثالثاً: دمج القيم الفارغة Nullish Coalescing

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

كثير من المطورين يلجؤون إلى المعامل || لتحديد قيمة افتراضية، لأنه يُعيد القيمة اليمنى إذا كانت القيمة اليسرى غير صالحة منطقياً.

استخدام المعامل المنطقي OR لتعيين قيمة افتراضية في جافاسكربت

لكن هنا تظهر مشكلة مهمة: المعامل || لا يفرّق بين القيم الفارغة فعلياً مثل undefined وnull، وبين القيم الصالحة التي تعتبر falsy مثل 0 أو ''.

مشكلة || مع القيم الصالحة

const value1 = 0 || 'default string';
console.log(value1);

const value2 = '' || 1000;
console.log(value2);

في المثال السابق، قد تتوقع أن تكون قيمة value1 هي 0 لأن الصفر قيمة موجودة فعلاً، وأن تكون قيمة value2 هي السلسلة الفارغة ''. لكن ما يحدث هو أن || يتعامل معهما كقيم غير صالحة ويعيد القيم الافتراضية.

ناتج استخدام المعامل OR مع القيم صفر والسلسلة الفارغة في جافاسكربت

الحل الأفضل: استخدام ??

هنا يأتي دور Nullish Coalescing عبر المعامل ??. هذا المعامل يعيد القيمة الموجودة على اليمين فقط إذا كانت القيمة اليسرى undefined أو null، وليس إذا كانت 0 أو ''.

const value1 = 0 ?? 'default string';
console.log(value1);

const value2 = '' ?? 1000;
console.log(value2);

في هذه الحالة، ستكون النتيجة كما نتوقع تماماً: سيتم الاحتفاظ بالقيمة 0 والسلسلة الفارغة '' لأنهما قيمتان موجودتان وليستا null أو undefined.

ناتج استخدام المعامل Nullish Coalescing مع القيم صفر والسلسلة الفارغة في جافاسكربت

الفرق بين || و??

المعامل متى يعيد القيمة اليمنى؟ هل يعتبر 0 و'' قيماً مفقودة؟
|| عندما تكون القيمة اليسرى falsy نعم
?? عندما تكون القيمة اليسرى null أو undefined لا

لذلك، إذا كنت تريد قيمة افتراضية فقط عند غياب البيانات فعلاً، فغالباً يكون ?? هو الخيار الأدق.

متى تستخدم كل أسلوب؟

  • استخدم condition ? value1 : value2 عندما تريد كتابة شرط مختصر وواضح.
  • استخدم ?. عندما تصل إلى خصائص متداخلة قد لا تكون موجودة.
  • استخدم ?? عندما تريد تعيين قيمة افتراضية للقيم null أو undefined فقط.

أفضل الممارسات عند استخدام علامة ? في JavaScript

  • لا تفرط في استخدام المعامل الثلاثي داخل شروط متداخلة كثيرة حتى لا يصبح الكود صعب القراءة.
  • اعتمد على Optional Chaining عند التعامل مع البيانات الخارجية غير المضمونة.
  • فضّل ?? على || إذا كانت القيم مثل 0 و'' مهمة في منطق التطبيق.
  • احرص على أن يكون الكود واضحاً للمطورين الآخرين، فاختصار الكود لا يعني دائماً أنه الأفضل.

الخلاصة التقنية

علامة ? في JavaScript ليست مجرد رمز بسيط، بل تمثل ثلاث أدوات قوية تخدم أهدافاً مختلفة: اختصار الشروط عبر Ternary Operator، وتأمين الوصول إلى الخصائص عبر Optional Chaining، والتعامل الذكي مع القيم المفقودة باستخدام Nullish Coalescing. من الناحية العملية، فهم الفرق بين هذه الاستخدامات يرفع جودة الكود ويقلل الأخطاء ويجعل التطبيقات أكثر مرونة، خصوصاً في المشاريع التي تتعامل مع بيانات ديناميكية ومتغيرة باستمرار.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *