השם המוזר הזה מסתיר מאחוריו פיצ'ר מאוד חשוב ואופרטור חדש ומעניין של 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.
3 תגובות
אוטטו 2020 , לא מבין את הטירוף של העולם לעבוד עם שפה נחותה.
כנראה כולם מטומטמים ואתה חכם
אתה פיצול אישיות???