ג'אווה סקריפט היא שפה עם טיפוסיות דינמית (Dynamically Typed Language), כלומר משתנים יכולים להחזיק ערכים מסוגים שונים בזמנים שונים. הבנת סוגי הנתונים (Data Types) היא הבסיס לכתיבת קוד יעיל ולמניעת באגים נפוצים.
במדריך זה תלמדו על כל סוגי הנתונים ב-JavaScript, כיצד לבדוק סוגים עם typeof, את ההבדל בין null ל-undefined, וכיצד JavaScript מטפלת בהמרת סוגים.
ל-JavaScript יש 7 סוגי נתונים פרימיטיביים (String, Number, Boolean, Null, Undefined, Symbol, BigInt) וסוג מבני אחד (Object). מערכים ופונקציות הם טכנית אובייקטים, אבל הם מתנהגים אחרת ולעיתים נדונים כסוגים נפרדים.
TL;DR
הטבלה הבאה מסכמת את כל סוגי הנתונים ב-JavaScript:
| סוג נתון | תיאור | דוגמה |
|---|---|---|
| String | מייצג נתונים טקסטואליים | let name = "John"; |
| Number | מייצג ערכים מספריים (שלמים ונקודה צפה) | let age = 30; |
| Boolean | מייצג ערכים לוגיים: true או false | let isActive = true; |
| Null | מייצג היעדר מכוון של ערך | let emptyValue = null; |
| Undefined | מציין שמשתנה לא הוקצה לו ערך | let value; |
| Symbol | מייצג מזהה ייחודי ובלתי ניתן לשינוי | let sym = Symbol('id'); |
| BigInt | מייצג מספרים שלמים עם דיוק שרירותי | let big = 9007199254740993n; |
| Object | מייצג אוסף של צמדי מפתח-ערך | let person = { name: 'John' }; |
| Array | מייצג אוסף מסודר של ערכים | let numbers = [1, 2, 3]; |
| Function | מייצג קטעי קוד לשימוש חוזר | function greet() { return "Hello"; } |
סוגי נתונים פרימיטיביים
סוגי נתונים פרימיטיביים הם ערכים בלתי ניתנים לשינוי (immutable) שנשמרים ישירות במשתנה. כאשר מקצים ערך פרימיטיבי למשתנה אחר, JavaScript מעתיקה את הערך. ישנם 7 סוגים פרימיטיביים:
1. String
מחרוזות מייצגות טקסט ונוצרות באמצעות גרשיים בודדים, גרשיים כפולים, או גרשיים הפוכים (template literals):
let greeting = 'Hello, World!';
let name = "John Doe";
let message = `Hello, ${name}!`;2. Number
מספרים מייצגים ערכים שלמים וערכים עם נקודה צפה. JavaScript משתמשת בסוג Number יחיד לכל הערכים המספריים:
let age = 30;
let pi = 3.14;
let largeNumber = 1e6; // 1000000ל-JavaScript יש גם ערכים מספריים מיוחדים:
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log('hello' * 2); // NaN (Not a Number)
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991NaN הוא ערך מיוחד שמציין פעולה מספרית שנכשלה. הוא ייחודי בכך ש-NaN !== NaN – השתמשו ב-Number.isNaN() כדי לבדוק אותו.
3. Boolean
ערכי Boolean מייצגים ערכים לוגיים: true או false.
let isActive = true;
let isComplete = false;4. Null
Null מייצג היעדר מכוון של ערך. מקצים null באופן מפורש כדי לציין "אין ערך":
let emptyValue = null;
console.log(emptyValue); // null5. Undefined
Undefined מציין שמשתנה הוצהר אך לא הוקצה לו ערך:
let undefinedValue;
console.log(undefinedValue); // undefinedNull מול Undefined: שניהם מייצגים "אין ערך", אבל הם שונים בכוונה. השתמשו ב-null כשאתם רוצים לאפס משתנה באופן מכוון. undefined משמעו שהמשתנה מעולם לא קיבל ערך. בפועל, השתמשו ב-null בקוד שלכם והתייחסו ל-undefined כ"עדיין לא הוגדר".
6. Symbol
Symbols הם מזהים ייחודיים ובלתי ניתנים לשינוי, ומשמשים לעיתים כמפתחות של תכונות אובייקט כדי להימנע מהתנגשויות שמות:
let symbol1 = Symbol('description');
let symbol2 = Symbol('description');
console.log(symbol1 === symbol2); // false (כל Symbol הוא ייחודי)7. BigInt
BigInt מייצג מספרים שלמים גדולים מ-Number.MAX_SAFE_INTEGER (2^53 – 1). יוצרים BigInt על ידי הוספת n לסוף המספר:
let bigIntValue = 9007199254740993n;
console.log(bigIntValue + 1n); // 9007199254740994nלא ניתן לערבב BigInt עם מספרים רגילים בפעולות חשבון – יש להמיר סוג אחד קודם.
סוגי נתונים של אובייקטים
אובייקטים הם סוגי ייחוס (reference types). בניגוד לפרימיטיביים, כאשר מקצים אובייקט למשתנה אחר, שני המשתנים מצביעים על אותם נתונים בזיכרון.
1. Object
אובייקטים הם אוסף של צמדי מפתח-ערך:
let person = {
name: 'John',
age: 30
};
console.log(person.name); // John2. Array
מערכים הם אוסף מסודר של ערכים:
let numbers = [1, 2, 3, 4, 5];
console.log(numbers[0]); // 13. Function
פונקציות הן קטעי קוד לשימוש חוזר:
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet('Alice')); // Hello, Alice!בדיקת סוגי נתונים עם typeof
האופרטור typeof מחזיר מחרוזת שמציינת את סוג הערך:
typeof 'hello' // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof undefined // "undefined"
typeof null // "object" (באג ידוע ב-JavaScript)
typeof Symbol('id') // "symbol"
typeof 10n // "bigint"
typeof {} // "object"
typeof [] // "object"
typeof function(){} // "function"שימו לב ש-typeof null מחזיר "object" – זהו באג היסטורי ב-JavaScript שלא תוקן מעולם מסיבות של תאימות לאחור. כדי לבדוק null, השתמשו ב-value === null.
כדי להבדיל בין מערכים לאובייקטים, השתמשו ב-Array.isArray():
Array.isArray([1, 2, 3]); // true
Array.isArray({ a: 1 }); // falseערכי Truthy ו-Falsy
לכל ערך ב-JavaScript יש "אמיתיות" (truthiness) בוליאנית מובנית. כאשר ערך מופיע בהקשר בוליאני (כמו הצהרת if), הוא מומר ל-true או false.
ערכי Falsy (מוערכים כ-false):
false
0
-0
0n // BigInt zero
"" // מחרוזת ריקה
null
undefined
NaNכל השאר הוא truthy, כולל מערכים ריקים [] ואובייקטים ריקים {}:
if ([]) console.log('empty array is truthy'); // מודפס
if ({}) console.log('empty object is truthy'); // מודפס
if ('0') console.log('string "0" is truthy'); // מודפסהמרת סוגים (Type Coercion)
JavaScript ממירה אוטומטית ערכים בין סוגים כשצריך. תהליך זה נקרא המרת סוגים (type coercion), והוא יכול להוביל לתוצאות לא צפויות אם אינכם מודעים לכך:
console.log('5' + 3); // "53" (מספר הומר למחרוזת)
console.log('5' - 3); // 2 (מחרוזת הומרה למספר)
console.log(true + 1); // 2 (true הומר ל-1)
console.log(null + 1); // 1 (null הומר ל-0)
console.log('' == 0); // true (שניהם הומרו)כדי להימנע מבאגים הקשורים להמרת סוגים, השתמשו בהשוואה מחמירה (===) במקום השוואה רופפת (==):
console.log(0 == ''); // true (רופף - מתרחשת המרת סוגים)
console.log(0 === ''); // false (מחמיר - סוגים שונים)שאלות נפוצות
שאלות נפוצות על סוגי נתונים ב-JavaScript:
undefined הוא ערך ברירת המחדל של JavaScript למשתנים שהוצהרו אך לא קיבלו ערך. null הוא ערך שמקצים באופן מפורש כדי לציין "ריק באופן מכוון". בפועל, השתמשו ב-null כשרוצים לאפס משתנה, והתייחסו ל-undefined כ"עדיין לא הוגדר".null יוצג כמצביע null (0x00), שחלק את אותה תגית של אובייקטים. הבאג לא תוקן מעולם כי שינוי שלו ישבור קוד קיים. כדי לבדוק null, השתמשו ב-value === null במקום ב-typeof.Array.isArray(value). האופרטור typeof מחזיר "object" גם למערכים וגם לאובייקטים רגילים, ולכן הוא לא יכול להבדיל ביניהם. Array.isArray([1, 2]) מחזיר true, בעוד Array.isArray({ a: 1 }) מחזיר false.== (השוואה רופפת) ממיר את שני הערכים לאותו סוג לפני ההשוואה, מה שיכול לגרום לתוצאות לא צפויות כמו 0 == "" שמחזיר true. האופרטור === (השוואה מחמירה) משווה גם ערך וגם סוג ללא המרה, כך ש-0 === "" מחזיר false. העדיפו תמיד === אלא אם אתם צריכים במפורש המרת סוגים.BigInt כשצריכים לעבוד עם מספרים שלמים גדולים מ-Number.MAX_SAFE_INTEGER (9,007,199,254,740,991). מקרי שימוש נפוצים כוללים עבודה עם מזהי מסד נתונים, ערכים קריפטוגרפיים, או חותמות זמן בדיוק גבוה. שימו לב ש-BigInt לא ניתן לערבב עם ערכי Number רגילים בחשבון - יש להמיר סוג אחד קודם.סיכום
ל-JavaScript יש 7 סוגי נתונים פרימיטיביים (String, Number, Boolean, Null, Undefined, Symbol, BigInt) וסוג ייחוס אחד (Object). פרימיטיביים הם בלתי ניתנים לשינוי ומועתקים לפי ערך, בעוד אובייקטים מועתקים לפי הפניה.
השתמשו באופרטור typeof כדי לבדוק סוגי נתונים, אבל זכרו את המוזרויות שלו: typeof null מחזיר "object" ו-typeof [] גם מחזיר "object". השתמשו ב-Array.isArray() וב-=== null לבדיקות מדויקות.
הבנת המרת סוגים וערכי truthy/falsy תעזור לכם להימנע מבאגים נפוצים. העדיפו תמיד השוואה מחמירה (===) כדי למנוע המרות סוגים לא צפויות.

