מחלקת `Number` ב-JavaScript
מאמר זה מסביר את מחלקת Number ב-JavaScript.
נסביר בזהירות את המאפיינים של Number, מלכודות נפוצות, APIs שימושיים, ודוגמאות מעשיות שלב אחר שלב.
YouTube Video
מחלקת Number ב-JavaScript
Number הוא טיפוס המספרים הבסיסי ב-JavaScript ומיוצג כמספר נקודה צפה בדיוק כפול (64-ביט) לפי תקן IEEE-754.
יסודות: ייצוג מספרים ובדיקת טיפוס
ב-JavaScript, כל המספרים מיוצגים כטיפוס הבסיסי number.
1// Primitive numbers and Number object
2const a = 42; // primitive number
3const b = 3.14; // primitive float
4const c = Number(10); // primitive via constructor call (function form)
5const d = new Number(10); // Number object (wrapper)
6
7console.log(typeof a); // "number"
8console.log(typeof d); // "object"
9console.log(c == d); // true (value coerces)
10console.log(c === d); // false (different types)
- הקוד הזה מדגים את ההבדל בין טיפוס פרימיטיבי
numberלבין האובייקט העוטףNumber. בדרך כלל נעשה שימוש בערכים בסיסיים (primitives) במקום עוטפים (wrappers).
ערכים מיוחדים: NaN, Infinity וקבועים
Number מספק ערכים מיוחדים (NaN, Infinity) וקבועים.
1// Special numeric values and constants
2console.log(Number.NaN); // NaN
3console.log(Number.POSITIVE_INFINITY); // Infinity
4console.log(Number.NEGATIVE_INFINITY); // -Infinity
5
6console.log(Number.MAX_VALUE); // largest positive representable
7console.log(Number.MIN_VALUE); // smallest positive representable (closest to 0)
8console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
9console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
10console.log(Number.EPSILON); // smallest difference ~2.220446049250313e-16
- מספרים שלמים הגדולים או שווים ל-
MAX_SAFE_INTEGERעשויים לא להיות מיוצגים בדיוק. שקול להשתמש ב-BigIntאם דרושה דיוק גבוה.EPSILONמשמש להשוואת מספרים בנקודה צפה.
המרת מספרים: Number(), parseInt, parseFloat, והאופרטור +
ישנן מספר דרכים להמיר מחרוזת למספר, שלכל אחת מהן התנהגות שונה.
1// Converting strings to numbers
2console.log(Number("42")); // 42
3console.log(Number(" 3.14 ")); // 3.14
4console.log(+ "7"); // 7 (unary +)
5
6console.log(parseInt("42px")); // 42
7console.log(parseFloat("3.14abc"));// 3.14
8
9// Careful with parseInt and radix
10console.log(parseInt("08")); // 8
11console.log(parseInt("08", 10)); // 8 (explicit radix is safer)
Number()מחזירNaNאלא אם כל המחרוזת בפורמט מספרי בלבד, בעוד ש-parseIntו-parseFloatמפענחים את החלק המספרי שקיים בתחילת המחרוזת. בטוח יותר לציין תמיד את בסיס המספר (radix) בעת שימוש ב-parseInt.
טיפול ובדיקה של NaN: הפונקציות isNaN ו-Number.isNaN
NaN (לא מספר) הוא מיוחד כי NaN !== NaN. יש הבדל באופן הבדיקה; isNaN הגלובלית מבצעת המרת טיפוס ועלולה לגרום לתוצאות חיוביות שגויות, לכן מומלץ להשתמש ב-Number.isNaN.
1// NaN detection differences
2console.log(NaN === NaN); // false
3
4console.log(isNaN("foo")); // true -> because "foo" coerces to NaN
5console.log(Number.isNaN("foo")); // false -> "foo" is not the numeric NaN
6
7console.log(Number.isNaN(NaN)); // true
- השתמש ב-
Number.isNaNלבדיקה של מספרים ואימות תוצאות חישוב כדי להימנע מהמרות טיפוס מיותרות.
שגיאות נקודה צפה והשוואות בעזרת Number.EPSILON
בגלל תקן IEEE-754, מתרחשות שגיאות כמו 0.1 + 0.2 !== 0.3. להשוואות מדויקות נהוג להשתמש בהפרש ו-Number.EPSILON.
1// Floating point precision example and EPSILON comparison
2const sum = 0.1 + 0.2;
3console.log(sum === 0.3); // false
4
5function nearlyEqual(a, b, epsilon = Number.EPSILON) {
6 return Math.abs(a - b) <= epsilon * Math.max(1, Math.abs(a), Math.abs(b));
7}
8
9console.log(nearlyEqual(sum, 0.3)); // true
- כשמתירים שגיאות בהשוואה, מומלץ ליישם פונקציה חזקה כמו
nearlyEqual, שמבצעת גם קנה מידה וגם משתמשת בהפרשים מוחלטים.
בדיקת שלמים ושלמים בטוחים (isInteger, isSafeInteger)
יש APIs שמאפשרים לבדוק אם ערך הוא שלם ואם הוא נמצא בתחום המספרים השלמים הבטוחים.
1// Integer and safe integer checks
2console.log(Number.isInteger(3)); // true
3console.log(Number.isInteger(3.0)); // true
4console.log(Number.isInteger(3.1)); // false
5
6console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); // true
7console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false
- כאשר נדרשת דיוק עבור שלמים גדולים, השתמש ב-
Number.isSafeIntegerלבדיקה, ושקול להשתמש ב-BigIntעבור מספרים שמעל הטווח.
הצגה ועיצוב: toFixed, toPrecision, toString
ישנן שיטות לשליטה על אופן ההצגה של מספרים. toFixed מחזיר מחרוזת עם מספר ספרות אחרי הנקודה בהתאם למשתנה שניתן, אך יש לשים לב לעיגול.
1// Formatting numbers for display
2const x = 1.23456;
3console.log(x.toFixed(2)); // "1.23" (string)
4console.log(x.toPrecision(3)); // "1.23" (string with total significant digits)
5console.log((255).toString(16)); // "ff" (hexadecimal string)
toFixedמחזיר מחרוזת, לכן יש לשים לב לערכים לאחר המרה למספרים לצורך חישובים.
זהירות לגבי שרשור מחרוזות ואופרטור +
האופרטור + משמש גם לחיבור מספרים וגם לשרשור מחרוזות, ולכן עשויות להתרחש תוצאות לא צפויות בהתאם לטיפוסי הנתונים.
1// Pitfall with + operator and type coercion
2console.log(1 + 2 + "px"); // "3px"
3console.log("px" + 1 + 2); // "px12"
4console.log(1 + "2" - 0); // 3 (string coerced to number for subtraction)
- כאשר מערבבים מחרוזות ומספרים, בטוח יותר להשתמש במפורש ב-
String(),Number()או ב-template literals כדי להימנע מהמרות טיפוס מרומזות.
שימושים מתקדמים: Number.parseInt / Number.parseFloat, valueOf
Number.parseInt ו-Number.parseFloat הן כינויים לפונקציות הגלובליות. valueOf משמש לקבלת הערך הבסיסי מתוך אובייקט Number, אך לרוב אין בו צורך מעשי.
1// Number.parseInt/parseFloat aliases and valueOf example
2console.log(Number.parseInt("100", 10)); // 100
3console.log(Number.parseFloat("3.14")); // 3.14
4
5const nObj = new Number(5);
6console.log(nObj.valueOf()); // 5
7console.log(nObj + 1); // 6 (object coerced to primitive)
- בעת שימוש ב-
Number.parseIntו-Number.parseFloat, יש לשים לב לבסיס המספר (radix) ולחיתוך (trimming) הקלט. נהוג בדרך כלל להימנע משימוש בעוטפי טיפוסים (Wrapper objects).
הפניה: דוגמת עזר קטנה - פונקציות לאימות מספרים
להלן פונקציות עזר קטנות שמאגדות בדיקות נפוצות. דבר זה מקל על משימות כגון אימות קלט.
1// Small number utility functions
2function toNumberStrict(value) {
3 // Return a Number or throw for invalid numeric strings
4 const n = Number(value);
5 if (typeof value === "string" && value.trim() === "") {
6 throw new Error("Empty string is not a valid number");
7 }
8 if (Number.isNaN(n)) {
9 throw new Error(`Invalid number: ${value}`);
10 }
11 return n;
12}
13
14function almostEqual(a, b, eps = Number.EPSILON) {
15 // Robust relative comparison
16 return Math.abs(a - b) <= eps * Math.max(1, Math.abs(a), Math.abs(b));
17}- אלו פונקציות שימושיות במיוחד שיכולות לשמש לעיבוד קלט ולהשוואות שוב ושוב. מימושים שזורקים חריגות (errors) מועילים למטרות ולידציה.
סיכום ביצועים והמלצות לשימוש מיטבי
להלן נקודות מעשיות לשימוש ב-Number.
- בעיקרון, השתמש בטיפוס
numberהבסיסי והימנע משימוש ב-new Number(). - בחר בין
Number()(מדויק) אוparseInt/parseFloat(חילוץ חלקי) להמרת מחרוזת למספר בהתאם לצורך. - השתמש ב-
Number.isNaNו-Number.isFiniteלבדיקות בטוחות. - להשוואות מספרים בנקודה צפה השתמש ב-
Number.EPSILONאו כתוב פונקציה להשוואה ייעודית. - כשדרושה דיוק בשלם, בדוק עם
Number.isSafeInteger, ואם חורגים מהטווח, השתמש ב-BigInt. - אתה יכול להשתמש ב-
toFixedאוtoPrecisionלעיגול בעת תצוגה, אך שים לב שערך ההחזרה הוא מחרוזת.
סיכום
Number הוא הטיפוס הבסיסי לכל המספרים ב-JavaScript, כולל שלמים, עשרוניים וערכים מיוחדים (NaN ו-Infinity). חשוב לשים לב להמרות טיפוס ולשגיאות נקודה צפה, ולהשתמש נכון בשיטות כמו Number.isNaN ו-Number.EPSILON. אם חורגים מטווח המספרים השלמים הבטוחים, השתמש ב-BigInt ועבור עיגול או הצגה השתמש ב-toFixed או toPrecision.
תוכלו לעקוב אחר המאמר שלמעלה באמצעות Visual Studio Code בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.