Lesson 13 / الدرس 13

Optional chaining and ?? / التسلسل الاختياري و??

Two small operators that between them remove most of the defensive clutter from code that reads data it did not create. One stops a chain safely; the other supplies a default without swallowing zero.

مؤثران صغيران يزيلان بينهما معظم الفوضى الدفاعية من شيفرة تقرأ بيانات لم تنشئها. أحدهما يوقف سلسلة بأمان، والآخر يوفّر قيمة افتراضية دون ابتلاع الصفر.

Stopping instead of crashing

order.customer.name        crashes if there is no customer
order.customer?.name       gives undefined instead

items?.[0]                 the same, for index access
callback?.()               the same, for calling a function

value ?? 'default'         used only when value is null or undefined
value || 'default'         used when value is ANY falsy — including 0
The question mark says: if the thing on my left is null or undefined, stop here and hand back undefined; otherwise carry on. It is not a general error catcher — a genuine typo still fails, which is what you want. Run it.

Why ?? exists at all

For years the way to write a default was value || fallback, and it is wrong whenever a legitimate value is falsy. A quantity of 0, an empty note, a checkbox set to false — all three are real answers that || silently replaces with the fallback. The classic bug is a shopping cart that refuses to show a quantity of zero. ?? looks only for null and undefined, which is what "no value was supplied" actually means.

WrittenWhen the left side is missing
a?.bundefined, no crash
a?.[i]undefined, no crash
fn?.()undefined, and the call never happens
a ?? bb, but only for null and undefined
a || bb for 0, empty string and false as well

The third row is quietly useful for optional callbacks: onDone?.() replaces the if (typeof onDone === "function") guard that used to surround every one.

Try it live / جرّب بنفسك

Preview / المعاينة

Check yourself / اختبر نفسك

1. What does order.customer?.name give when there is no customer?

2. Why is quantity || 1 a bug?

3. When should you NOT reach for optional chaining?

Your task / مهمتك

Take a nested object describing an order and read four values out of it with optional chaining, at least one of them three levels deep and at least one that stops early. Print the crash you get without the question mark. Then build a table comparing ?? and || across 0, the empty string, false, null and a real value, and write one sentence under it naming a case where || would be the actual bug in a real page.

خذ كائنًا متداخلًا يصف طلبًا واقرأ منه أربع قيم بالتسلسل الاختياري، واحدة منها على الأقل بعمق ثلاثة مستويات وواحدة على الأقل تقف مبكرًا. واطبع الانهيار الذي تحصل عليه بلا علامة الاستفهام. ثم ابنِ جدولًا يقارن ?? و|| عبر 0 والنص الفارغ وfalse وnull وقيمة حقيقية، واكتب تحته جملة تسمّي حالة يكون فيها || هو الخلل الفعلي في صفحة حقيقية.

  • Four reads, one three levels deep, one stopping early أربع قراءات، واحدة بعمق ثلاثة وواحدة تقف مبكرًا
  • The crash without ?. shown الانهيار بلا ?. معروضًا
  • A ?? versus || comparison over five values مقارنة ?? مقابل || عبر خمس قيم
  • One named real-page bug caused by || خلل صفحة حقيقي واحد مسمّى سببه ||
How do you want to submit? / كيف تريد التسليم؟