לדלג לתוכן

2.2 משתנים, טיפוסים ואופרטורים פתרון

פתרון - משתנים, טיפוסים ואופרטורים

פתרון תרגיל 1

var a = 1;
let b = 2;
const c = 3;

a = 10;   // ok - var can be reassigned
b = 20;   // ok - let can be reassigned
// c = 30; // TypeError: Assignment to constant variable - const can't be reassigned

console.log(a); // 10
console.log(b); // 20
console.log(c); // 3

var a = 100;   // allowed! var can be re-declared
// let b = 200; // SyntaxError: 'b' has already been declared
// const c = 300; // SyntaxError: 'c' has already been declared

console.log(a); // 100
  • var מאפשר גם לשנות ערך וגם להגדיר מחדש - זה בעייתי ולכן לא משתמשים בו
  • let מאפשר לשנות ערך אבל לא להגדיר מחדש
  • const לא מאפשר שינוי ולא הגדרה מחדש

פתרון תרגיל 2

console.log(typeof 42);            // "number"
console.log(typeof "42");          // "string"
console.log(typeof true);          // "boolean"
console.log(typeof undefined);     // "undefined"
console.log(typeof null);          // "object" (known bug!)
console.log(typeof NaN);           // "number" (NaN is technically a number type)
console.log(typeof [1, 2, 3]);     // "object" (arrays are objects in JS)
console.log(typeof {name: "Alice"}); // "object"
  • typeof null מחזיר "object" - זה באג ידוע מ-1995
  • typeof NaN מחזיר "number" - NaN הוא ערך מטיפוס number שאומר "זה לא מספר תקין"
  • מערכים הם אובייקטים בJS, לכן typeof מחזיר "object" גם להם. כדי לבדוק אם משהו הוא מערך: Array.isArray([1,2,3])

פתרון תרגיל 3

console.log("5" + 3);          // "53" (string + number = concatenation)
console.log("5" - 3);          // 2 (string - number = math)
console.log("5" * "2");        // 10 (both converted to numbers)
console.log("hello" - 1);      // NaN ("hello" can't become a number)
console.log(true + true);      // 2 (true = 1, so 1 + 1)
console.log(false + "1");      // "false1" (false becomes string "false", then concatenation)
console.log("" + 0);           // "0" (empty string + number = concatenation)
console.log(null + 1);         // 1 (null becomes 0)
console.log(undefined + 1);    // NaN (undefined becomes NaN)
console.log("3" + 4 + 5);      // "345" (left to right: "3"+4="34", "34"+5="345")
console.log(3 + 4 + "5");      // "75" (left to right: 3+4=7, 7+"5"="75")

השורות האחרונות הן הכי מעניינות - הסדר חשוב! JS מעבד משמאל לימין.

פתרון תרגיל 4

console.log(5 == "5");           // true (type coercion: "5" becomes 5)
console.log(5 === "5");          // false (different types, no coercion)
console.log(0 == false);         // true (false becomes 0)
console.log(0 === false);        // false (different types)
console.log(null == undefined);  // true (special rule: null == undefined is true)
console.log(null === undefined); // false (different types)
console.log("" == false);       // true (both become 0)
console.log("" === false);      // false (different types)
console.log(NaN == NaN);        // false (NaN is never equal to anything, including itself!)
console.log(NaN === NaN);       // false (same - NaN is never equal to NaN)
  • NaN הוא הערך היחיד ב-JS שלא שווה לעצמו, גם עם == וגם עם ===
  • null == undefined הוא true כחוק מיוחד בשפה, אבל === מחזיר false כי הטיפוסים שונים
  • לכן תמיד משתמשים ב-=== - זה צפוי ובטוח

פתרון תרגיל 5

function checkTruthy(value) {
    if (value) {
        console.log(`${value} is truthy`);
    } else {
        console.log(`${value} is falsy`);
    }
}

checkTruthy(0);         // "0 is falsy"
checkTruthy("");        // " is falsy"
checkTruthy("0");       // "0 is truthy"     (non-empty string!)
checkTruthy(null);      // "null is falsy"
checkTruthy(undefined); // "undefined is falsy"
checkTruthy(false);     // "false is falsy"
checkTruthy([]);        // " is truthy"      (empty array is truthy in JS!)
checkTruthy({});        // "[object Object] is truthy"  (empty object is truthy!)
checkTruthy(NaN);       // "NaN is falsy"
checkTruthy("false");   // "false is truthy" (the STRING "false", not the boolean!)
checkTruthy(-1);        // "-1 is truthy"    (any non-zero number is truthy)
checkTruthy(1);         // "1 is truthy"
  • מחרוזת ריקה "" היא falsy, אבל "0" ו-"false" הם truthy כי הם מחרוזות לא ריקות
  • מערך ריק [] ואובייקט ריק {} הם truthy ב-JS - שונה מפייתון!

פתרון תרגיל 6

א. Ternary:

let age = 20;
let category = age >= 18 ? "adult" : "minor";

ב. Nullish coalescing:

let userInput = null;
let name = userInput ?? "Anonymous";

ג. ההבדל:

let value1 = 0 || "default";  // "default" (0 is falsy, so || returns right side)
let value2 = 0 ?? "default";  // 0 (0 is not null/undefined, so ?? keeps it)

  • || מחליף כל ערך falsy כולל 0 ומחרוזת ריקה
  • ?? מחליף רק null ו-undefined
  • אם 0 הוא ערך לגיטימי (למשל ציון, מחיר), צריך ?? ולא ||

פתרון תרגיל 7

let name = prompt("Enter your name:");
let age = Number(prompt("Enter your age:"));

let status;
let canDrive;

if (age >= 18) {
    status = "adult";
    canDrive = true;
} else {
    status = "minor";
    canDrive = false;
}

console.log(`${name} is ${age} years old`);
console.log(`Status: ${status}`);
console.log(`Can drive: ${canDrive}`);

if (name === "" || name === null) {
    console.log("No name provided");
} else {
    console.log(`Hello, ${name}!`);
}

הבדלים מפייתון:
- input() הפך ל-prompt()
- int() הפך ל-Number()
- True/False הפכו ל-true/false
- is_student הפך ל-isStudent (camelCase)
- f"..." הפך ל-`...`
- is None הפך ל-=== null
- or הפך ל-||

פתרון תרגיל 8

let celsiusInput = prompt("Enter temperature in Celsius:");
let celsius = Number(celsiusInput);
let fahrenheit = celsius * 9 / 5 + 32;

let message = celsius > 30 ? "Hot!" : "Nice weather";

alert(`${celsius}C = ${fahrenheit}F - ${message}`);

פתרון תרגיל 9

const student = {
    name: "Alice",
    grades: {
        math: 95,
        english: 88
    },
    address: null
};

console.log(student.name);                       // "Alice"
console.log(student.grades?.math ?? "N/A");       // 95
console.log(student.grades?.history ?? "N/A");     // "N/A"
console.log(student.address?.city ?? "N/A");       // "N/A"
console.log(student.parent?.name ?? "N/A");        // "N/A"
  • student.grades?.history - grades קיים אבל history לא, מחזיר undefined
  • student.address?.city - address הוא null, אז ?. מחזיר undefined בלי שגיאה
  • student.parent?.name - parent לא קיים, ?. מחזיר undefined בלי שגיאה
  • ?? "N/A" מחליף undefined ב-"N/A"

פתרון תרגיל 10

console.log([] + []);        // ""
// two empty arrays converted to strings ("" + ""), result is ""

console.log([] + {});        // "[object Object]"
// [] becomes "", {} becomes "[object Object]", concatenation result

console.log(typeof NaN);     // "number"
// NaN stands for "Not a Number" but its TYPE is number
// it's a special value within the number type that means "invalid number"

console.log(0.1 + 0.2 === 0.3); // false
// 0.1 + 0.2 = 0.30000000000000004 due to floating point precision
// this is not unique to JS - it happens in most languages including Python

console.log("b" + "a" + +"a" + "a"); // "baNaNa"
// +"a" tries to convert "a" to a number, gets NaN
// "b" + "a" = "ba"
// "ba" + NaN = "baNaN" (NaN becomes string "NaN")
// "baNaN" + "a" = "baNaNa"

תשובות לשאלות

  1. null הוא ערך שהמתכנת מכניס במכוון כדי לומר "אין כאן ערך" (למשל let result = null;). undefined אומר שהמשתנה הוגדר אבל לא קיבל ערך (למשל let x; - ערכו של x הוא undefined). גם כשפונקציה לא מחזירה כלום, היא מחזירה undefined.

  2. == ממיר טיפוסים לפני ההשוואה, מה שגורם לתוצאות מפתיעות כמו "" == false שהוא true. === לא ממיר ונותן תוצאות צפויות ובטוחות.

  3. || מחזיר את הצד הימני אם הצד השמאלי הוא falsy (כולל 0, "", false). ?? מחזיר את הצד הימני רק אם הצד השמאלי הוא null או undefined. כשערכים כמו 0 או מחרוזת ריקה הם לגיטימיים, צריך ??.

  4. אם אתם כותבים תנאי כמו if (myArray) ומצפים שמערך ריק יהיה falsy (כמו בפייתון), תקבלו true ב-JS. צריך לבדוק if (myArray.length > 0) כדי לבדוק אם המערך לא ריק.

  5. const לא מאפשר שינוי של הערך - משתמשים בו כברירת מחדל. let מאפשר שינוי - משתמשים בו כשצריך לעדכן את הערך (למשל מונה בלולאה, סכום שמצטבר, ערך שמשתנה לפי תנאים).