Menu

Nullish Coalescing (??) ב-JavaScript: ערכי ברירת מחדל נכונים

איך האופרטור ?? בוחר ברירת מחדל רק כשהערך הוא null או undefined, ולמה זה עדיף על || ברוב ערכי ברירת המחדל בעולם האמיתי.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

ברירת מחדל חכמה יותר

ל-JavaScript תמיד היה קיצור לברירות מחדל: value || fallback. זה עובד ברוב המקרים, אבל יש בו באג מובנה: הוא מתייחס ל_כל_ ערך falsy כאל ערך חסר. 0, '' ו-false כולם מפעילים את ברירת המחדל, גם כשהם התשובה האמיתית.

אופרטור ה-nullish coalescing ?? מתקן את זה. הוא עובר לברירת המחדל רק עבור null או undefined:

0 ו-'' שורדים. null ו-undefined לא. זה כל האופרטור.

למה || לא מספיק

הנה הבאג הקלאסי ש-?? נועד למנוע:

המשתמש ביקש עוצמת קול 0 (שקט) וכינוי ריק. שניהם נדרסו בשקט, כי || לא יודע להבחין בין "חסר" לבין "falsy".

החליפו ל-??:

עכשיו 0 ו-'' עוברים בלי שינוי, ורק שדות שבאמת חסרים מקבלים את ברירת המחדל. כמעט תמיד זה מה שאתם רוצים.

המודל המנטלי

?? שואל שאלה אחת: האם הצד השמאלי הוא null או undefined? שום דבר אחר לא נחשב.

הערך השמאליleft || right מחזירleft ?? right מחזיר
nullrightright
undefinedrightright
0rightleft (0)
''rightleft ('')
falserightleft (false)
NaNrightleft (NaN)
כל אובייקטleftleft

בחרו ב-?? כשיש בנתונים שלכם ערכי falsy בעלי משמעות. בחרו ב-|| כשאתם באמת רוצים לדחות כל דבר falsy (מחרוזות ריקות, ספירות של אפס וכדומה). המקרה הזה קיים, אבל הוא נדיר יותר ממה שנהוג לחשוב.

Short-Circuit

כמו || ו-&&, גם ?? עושה short-circuit. אם הצד השמאלי אינו nullish, הצד הימני לא רץ בכלל:

expensiveDefault() רצה רק פעם אחת, עבור b. זה שימושי כשברירת המחדל שלכם היא קריאה לפונקציה, בקשת רשת או כל דבר אחר שעדיף לדלג עליו כשאין בו צורך.

השילוב עם Optional Chaining

?? ו-?. נוספו יחד ב-ES2020, והם תוכננו לעבוד כצוות. Optional chaining עובר על נתיב שאולי חסר ומחזיר undefined אם אחד השלבים חסר; nullish coalescing ממלא אז ברירת מחדל הגיונית:

בלי הצמד הזה, אותו קוד הוא שרשרת מכוערת של בדיקות && או try/catch. איתם, גישה בטוחה וברירות מחדל שפויות נכנסות בשורה אחת.

השמת Nullish: ??=

a ??= b מציב את b ב-a רק כש-a הוא null או undefined. זה אופרטור ההשמה הלוגית מסוג nullish, והוא עושה short-circuit: אם ל-a כבר יש ערך, הצד הימני לא מחושב.

שימו לב ש-verbose: false ו-retries: 0 נשמרים: ??= ממלא רק את מה שבאמת חסר. השוו ל-||=, שהיה דורס את שניהם.

קדימות וכלל הסוגריים

?? מסרב בכוונה להתערבב עם || או && בלי סוגריים. הקוד הזה זורק SyntaxError:

const x = a || b ?? c;   // SyntaxError

מתכנני השפה החליטו שהקדימות עמומה מספיק כדי שיהיה שווה לחייב אתכם להבהיר. הוסיפו סוגריים והכול בסדר:

קיבוצים שונים, תשובות שונות. הסוגריים אינם קישוט: הם אומרים לקוראים העתידיים (ולמפענח) למה התכוונתם.

זה לא אותו דבר כמו פרמטר ברירת מחדל

לפרמטרי ברירת מחדל בחתימת פונקציה יש כלל משלהם: הם נכנסים לפעולה רק כשהארגומנט הוא undefined, לא null. זה הבדל עדין לעומת ??, שמתייחס לשניהם באותו אופן.

אם אתם רוצים שגם null יפעיל את ברירת המחדל, השתמשו ב-?? בתוך גוף הפונקציה:

הבחנה קטנה, וקל למעוד עליה כש-API מחזיר לכם null במשמעות "לא הוגדר ערך".

מתי לבחור ב-??

השתמשו ב-?? כאופרטור ברירת המחדל שלכם, אלא אם יש לכם סיבה מסוימת שלא לעשות זאת. הוא זה שמתאים לאופן שבו רוב הנתונים מתנהגים בפועל: 0, '' ו-false הם בדרך כלל ערכים אמיתיים ששווה לשמור, ורק נתונים שבאמת חסרים ראויים לברירת מחדל. שמרו את || למקרים שבהם אתם באמת רוצים להחליף כל ערך falsy.

הבא בתור: מחלקות

זה הכול לגבי אובייקטים ומערכים: יש לכם את הכלים לבנות מבני נתונים ולנווט בהם בבטחה. הפרק הבא עובר לארגון התנהגות: מחלקות, ירושה ומערכת ה-prototype שמתחתיהן.

שאלות נפוצות

מה זה אופרטור ה-nullish coalescing ב-JavaScript?

?? מחזיר את הצד הימני שלו רק כשהצד השמאלי הוא null או undefined. אחרת הוא מחזיר את הצד השמאלי כמו שהוא. value ?? fallback היא הדרך המקובלת לספק ברירת מחדל בלי ליפול על ערכים falsy שהם בכל זאת תקינים, כמו 0 או ''.

מה ההבדל בין ?? לבין || ב-JavaScript?

|| עובר לברירת המחדל עבור כל ערך falsy: 0, '', false, NaN, null, undefined. ?? עובר לברירת המחדל רק עבור null ו-undefined. אם 0 או מחרוזת ריקה הם ערכים לגיטימיים בנתונים שלכם, השתמשו ב-??. אם אתם באמת רוצים לדחות כל ערך falsy, || עדיין נכון.

אפשר לשלב nullish coalescing עם optional chaining?

כן, וזה צמד נפוץ. user?.settings?.theme ?? 'light' עובר על השרשרת בבטחה, מחזיר undefined אם משהו בדרך חסר, ואז מציב במקומו 'light'. שני האופרטורים נוספו יחד ב-ES2020 בדיוק כדי לתמוך בדפוס הזה.

מה עושה האופרטור ??=?

a ??= b מציב את b ב-a רק אם a הוא כרגע null או undefined. זו השמה לוגית מסוג nullish, קיצור של a = a ?? b, אבל עם short-circuit: אם ל-a כבר יש ערך, הצד הימני אפילו לא מחושב. שימושי למילוי ברירות מחדל חסרות באובייקט אפשרויות.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל