חידת JavaScript - מחרוזת למספר

20/06/2024

מה מחזיר הקוד הבא? למה?

['1', '2'].map(parseInt)

תוכן עניינים

  1. פיתרון
  2. הסבר

1. פיתרון

הקוד מחזיר את המערך:

[ 1, NaN ]

אני מבין למה 1 בתא הראשון, אבל מאיפה הגיע ה NaN? ולמה parseFloat כן עובד שם?

> parseInt(2)
2

> ['1', '2'].map(parseFloat)
[ 1, 2 ]

2. הסבר

הסיפור פשוט אבל מזכיר ש JavaScript תמיד תישאר JavaScript. הפונקציה parseInt מקבלת למעשה שני פרמטרים, פרמטר ראשון הוא המחרוזת שצריך להפוך למספר ופרמטר שני הוא בסיס הספירה. כשמריצים אותה בתוך map הפרמטר הראשון שנשלח הוא הערך מהמערך והשני הוא האינדקס שלו, וכך מה שבאמת ניסינו להפעיל שם היה:

> parseInt('2', 1)
NaN

וזה כבר NaN כי אי אפשר לפענח את המחרוזת 2 כמספר בבסיס 1. ההתנהגות מוסברת בפיסקה הבאה מתוך התיעוד של parseInt:

if it's nonzero and outside the range of [2, 36] after conversion, the function will always return NaN

וככה זה נראה על כל המערך של בסיסי ספירה עד 99:

> Array(100).fill(0).map((_, i) => `${i}`).map(parseInt)
[
    0, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN,  10,  12,
   14,  16,  18,  20,  22,  24,  26,  28,  40,  43,  46,  49,
   52,  55,  58,  61,  64,  67,  90,  94,  98, 102, 106, 110,
  114, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN,
  NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN,
  NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN,
  NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN,
  NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN,
  NaN, NaN, NaN, NaN
]

ומה לגבי parseFloat? נו, היא לא מקבלת פרמטר שני ולכן מחזירה תמיד את התוצאה הנכונה.

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