אובייקטים

אובייקט הוא אוסף של מאפיינים (properties) ומתודות (methods) המתארים ישות אחת.


יצירת אובייקט

Object Literal (נפוץ ביותר)

const person = {
    name: "דן",
    age: 25,
    city: "תל אביב"
};

מאפיינים עם שמות מיוחדים

const obj = {
    "first name": "דן",     // רווח - חייבים גרשיים
    "my-key": "value",      // מקף
    123: "מספר כמפתח"        // מספר
};

גישה למאפיינים

Dot Notation (נקודה)

const person = {
    name: "דן",
    age: 25
};

console.log(person.name);  // "דן"
console.log(person.age);   // 25

Bracket Notation (סוגריים)

console.log(person["name"]);  // "דן"

// חובה עבור שמות מיוחדים
const obj = { "first name": "דן" };
console.log(obj["first name"]);  // "דן"

// שימושי עם משתנים
const key = "name";
console.log(person[key]);  // "דן"

שינוי והוספת מאפיינים

const person = {
    name: "דן"
};

// שינוי ערך קיים
person.name = "דנה";

// הוספת מאפיין חדש
person.age = 25;
person["city"] = "תל אביב";

console.log(person);
// { name: "דנה", age: 25, city: "תל אביב" }

מחיקת מאפיין

const person = {
    name: "דן",
    age: 25,
    city: "תל אביב"
};

delete person.city;
console.log(person);  // { name: "דן", age: 25 }

מתודות (Methods)

מתודה היא פונקציה שמוגדרת בתוך אובייקט:

const person = {
    name: "דן",
    age: 25,

    // מתודה
    greet: function() {
        console.log("שלום!");
    },

    // קיצור מודרני
    sayAge() {
        console.log(`אני בן ${this.age}`);
    }
};

person.greet();   // "שלום!"
person.sayAge();  // "אני בן 25"

this

המילה this מתייחסת לאובייקט שבו נמצאת המתודה:

const person = {
    name: "דן",
    age: 25,

    introduce() {
        console.log(`שמי ${this.name} ואני בן ${this.age}`);
    }
};

person.introduce();  // "שמי דן ואני בן 25"

זהירות עם Arrow Functions!

const person = {
    name: "דן",

    // ❌ Arrow function - this לא עובד כמצופה!
    greetArrow: () => {
        console.log(this.name);  // undefined
    },

    // ✅ פונקציה רגילה
    greetRegular() {
        console.log(this.name);  // "דן"
    }
};

בדיקת קיום מאפיין

const person = {
    name: "דן",
    age: 25
};

// אופרטור in
console.log("name" in person);  // true
console.log("city" in person);  // false

// hasOwnProperty
console.log(person.hasOwnProperty("name"));  // true

// בדיקת ערך
console.log(person.city !== undefined);  // true אם קיים

מעבר על אובייקט

for...in

const person = {
    name: "דן",
    age: 25,
    city: "תל אביב"
};

for (let key in person) {
    console.log(`${key}: ${person[key]}`);
}
// name: דן
// age: 25
// city: תל אביב

Object.keys - רשימת מפתחות

const keys = Object.keys(person);
console.log(keys);  // ["name", "age", "city"]

Object.values - רשימת ערכים

const values = Object.values(person);
console.log(values);  // ["דן", 25, "תל אביב"]

Object.entries - זוגות [key, value]

const entries = Object.entries(person);
console.log(entries);
// [["name", "דן"], ["age", 25], ["city", "תל אביב"]]

// שימוש בלולאה
for (let [key, value] of Object.entries(person)) {
    console.log(`${key}: ${value}`);
}

Destructuring

פירוק אובייקט למשתנים:

const person = {
    name: "דן",
    age: 25,
    city: "תל אביב"
};

// במקום:
// const name = person.name;
// const age = person.age;

// אפשר:
const { name, age } = person;
console.log(name);  // "דן"
console.log(age);   // 25

// עם שינוי שם
const { name: userName, age: userAge } = person;
console.log(userName);  // "דן"

// עם ברירת מחדל
const { country = "ישראל" } = person;
console.log(country);  // "ישראל"

// אובייקטים מקוננים
const user = {
    name: "דן",
    address: {
        city: "תל אביב",
        street: "רוטשילד"
    }
};
const { address: { city } } = user;
console.log(city);  // "תל אביב"

Spread Operator

העתקת אובייקט

const original = { a: 1, b: 2 };
const copy = { ...original };

copy.a = 99;
console.log(original.a);  // 1 (לא השתנה)

מיזוג אובייקטים

const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2 };
console.log(merged);  // { a: 1, b: 2, c: 3, d: 4 }

// עם override
const defaults = { color: "blue", size: "medium" };
const userSettings = { size: "large" };
const settings = { ...defaults, ...userSettings };
console.log(settings);  // { color: "blue", size: "large" }

Shorthand Properties

const name = "דן";
const age = 25;

// במקום:
const person1 = { name: name, age: age };

// אפשר:
const person2 = { name, age };
console.log(person2);  // { name: "דן", age: 25 }

Computed Property Names

const key = "dynamicKey";
const obj = {
    [key]: "ערך דינמי",
    [`prefix_${key}`]: "עם prefix"
};

console.log(obj.dynamicKey);        // "ערך דינמי"
console.log(obj.prefix_dynamicKey); // "עם prefix"

Object.assign

העתקה ומיזוג של אובייקטים:

const target = { a: 1 };
const source = { b: 2, c: 3 };

Object.assign(target, source);
console.log(target);  // { a: 1, b: 2, c: 3 }

// יצירת עותק
const copy = Object.assign({}, target);

Object.freeze ו-Object.seal

// freeze - לא ניתן לשנות, להוסיף או למחוק
const frozen = Object.freeze({ a: 1 });
frozen.a = 2;     // ❌ לא יעבוד
frozen.b = 3;     // ❌ לא יעבוד
delete frozen.a;  // ❌ לא יעבוד

// seal - ניתן לשנות, לא להוסיף או למחוק
const sealed = Object.seal({ a: 1 });
sealed.a = 2;     // ✅ עובד
sealed.b = 3;     // ❌ לא יעבוד
delete sealed.a;  // ❌ לא יעבוד

אובייקטים מקוננים

const company = {
    name: "TechCorp",
    employees: [
        { name: "דן", role: "developer" },
        { name: "דנה", role: "designer" }
    ],
    address: {
        city: "תל אביב",
        street: "רוטשילד",
        number: 42
    }
};

// גישה
console.log(company.address.city);  // "תל אביב"
console.log(company.employees[0].name);  // "דן"

// Optional Chaining
console.log(company.address?.zipCode);  // undefined (בלי שגיאה)

דוגמאות מעשיות

יצירת user factory

function createUser(name, age) {
    return {
        name,
        age,
        isAdult() {
            return this.age >= 18;
        },
        greet() {
            return `שלום, אני ${this.name}`;
        }
    };
}

const user = createUser("דן", 25);
console.log(user.greet());     // "שלום, אני דן"
console.log(user.isAdult());   // true

עדכון מאפיין בצורה אימטבילית

const user = { name: "דן", age: 25 };

// יצירת עותק עם שינוי
const updatedUser = { ...user, age: 26 };

console.log(user.age);         // 25 (לא השתנה)
console.log(updatedUser.age);  // 26

סיכום

פעולה תחביר
יצירה { key: value }
גישה obj.key או obj["key"]
הוספה/שינוי obj.key = value
מחיקה delete obj.key
בדיקת קיום "key" in obj
מפתחות Object.keys(obj)
ערכים Object.values(obj)
זוגות Object.entries(obj)
פירוק const { key } = obj
פריסה { ...obj }

בדקו את עצמכם

נסו לענות לבד לפני שאתם פותחים את התשובה.

  1. איך ניגשים לשדה ששמו שמור במשתנה key?

    1. obj.key
    2. obj->key
    3. obj.get(key)
    4. obj[key]
    הצגת התשובה

    תשובה ד. obj.key מחפש שדה בשם 'key'. סוגריים מרובעים משתמשים בערך של המשתנה.

  2. מה עושה const { name, age } = user?

    1. מוחק את השדות
    2. משווה אובייקטים
    3. יוצר אובייקט חדש
    4. פירוק (destructuring): יוצר משתנים name ו-age מהשדות
    הצגת התשובה

    תשובה ד. זה קיצור ל-const name = user.name; const age = user.age;

  3. איך יוצרים עותק רדוד של אובייקט עם שינוי שדה אחד?

    1. copy(user)
    2. { ...user, name: 'x' }
    3. user.name = 'x'
    4. user + { name: 'x' }
    הצגת התשובה

    תשובה ב. Spread מעתיק את כל השדות, והשדה שאחריו דורס. חיוני ב-React.