ES2020 Nullish coalescing Operator

כדאי תמיד להשאר מעודכנים! הרשמו לעדכונים של האתר במייל! - המייל יישלח כל יום ראשון בעשר בבוקר ויכיל אך ורק את המאמרים שהתפרסמו באינטרנט ישראל. ללא ספאם, ללא הצפות, ללא בלגנים. אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂

השם המוזר הזה מסתיר מאחוריו פיצ’ר מאוד חשוב ואופרטור חדש ומעניין של ES2020 ותוספת חשובה לג’אווהסקריפט.

אחת מהפרקטיקות היותר נפוצות לקביעת ערך דיפולטיבי של משתנה הוא באמצעוצת האופרטור || . כך למשל:

let myVar = undefined;
let a = myVar || 'default value';
console.log('a', a);  // default value

אנחנו מכניסים ערך חדש למשתנה a. ערכו של המשתנה תלוי – אם יש לנו myVar, אז משתנה a יקבל את הערך שלו. במידה ו-myVar הוא undefined. אנו מכניסים ערך דיפולטיבי.

זה עובד גם עם null:

let myVar = null;
let a = myVar || 'default value';
console.log('a', a);  // default value

הבעיה היא שגם אם הערך הוא מחרוזת ריקה, 0 או false, אנו נקבל את אותה התנהגות כמו ב-undefined\null. למשל:

let myVar = 0;
let a = myVar || 'default value';
console.log('a', a);  // default value

או:

let myVar = '';
let a = myVar || 'default value';
console.log('a', a);  // default value

וזה יכול להיות אולטרא בעייתי. למה? כי הרבה פעמים באפליקציה שלנו, הערכים 0, false או מחרוזת ריקה הם ערכים לגיטימיים שיש להם משמעות. חישבו למשל על אובייקט משתמש שאני מקבל מהשרת ואני משתמש בחלק מהפרמטרים שלו באיזושהו רכיב. אני לא יודע אם הערכים האלו קיימים בכלל באותו אובייקט.

הנה למשל דוגמה סופר ריאליסטית (לקחתי אותה מטיוטת ההצעה של ה-TC39). הערכים שאני מקבל מאובייקט מרוחק של הגדרות המשתמש הן רלוונטיות ועדיין הוא מקבל את הגדרות ברירת המחדל! כי מבחינת ה-II ערכים לגיטימיים כמו false, 0 או מחרוזת ריקה נחשבים כמו undefined/null.


const response = {
  settings: {
    height: 400,
    animationDuration: 0,
    headerText: '',
    showSplashScreen: false
  }
};

const headerText = response.settings.headerText || 'Hello, world!'; 
const animationDuration = response.settings.animationDuration || 300; 
const showSplashScreen = response.settings.showSplashScreen || true; 

console.log('headerText', headerText); // Potentially unintended. '' is falsy, result: 'Hello, world!'
console.log('animationDuration', animationDuration); // Potentially unintended. 0 is falsy, result: 300
console.log('showSplashScreen', showSplashScreen); // Potentially unintended. false is falsy, result: true

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

בדיוק בשביל זה יש לנו את האופרטור Nullish coalescing. האופרטור הזה, שנראה כך: ?? – הוא אופרטור שעובד בדיוק || אבל הוא מעריך כ-false רק undefined או null. ועכשיו הבעיה נפתרה לגמרי:

const response = {
  settings: {
    height: 400,
    animationDuration: 0,
    headerText: '',
    showSplashScreen: false
  }
};

const headerText = response.settings.headerText ?? 'Hello, world!'; 
const animationDuration = response.settings.animationDuration ?? 300; 
const showSplashScreen = response.settings.showSplashScreen ?? true; 

console.log('headerText', headerText); // ''
console.log('animationDuration', animationDuration); // 0
console.log('showSplashScreen', showSplashScreen); // false

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

See the Pen Nullish Coalescing by Ran Bar-Zik (@barzik-the-vuer) on CodePen.

כדאי תמיד להשאר מעודכנים! הרשמו לעדכונים של האתר במייל! - המייל יישלח כל יום ראשון בעשר בבוקר ויכיל אך ורק את המאמרים שהתפרסמו באינטרנט ישראל. ללא ספאם, ללא הצפות, ללא בלגנים. אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂

אהבתם? לא אהבתם? דרגו!


תגיות: פורסם בקטגוריה: ES20XX

אל תשארו מאחור! יש עוד מה ללמוד!

One comment on “ES2020 Nullish coalescing Operator
  1. חזי הגיב:

    אוטטו 2020 , לא מבין את הטירוף של העולם לעבוד עם שפה נחותה.

כתיבת תגובה

האימייל לא יוצג באתר.

רישום