04 - Objects
What are Objects?
Objects store collections of key-value pairs. They're perfect for representing real-world entities with properties.
const person = {
name: "Alice",
age: 25,
city: "NYC"
};
console.log(person.name); // "Alice"
console.log(person.age); // 25Creating Objects
// Object literal (most common)
const user = {
name: "Bob",
email: "bob@example.com"
};
// Empty object
const empty = {};
// Object constructor (rarely used)
const obj = new Object();
obj.name = "Alice";Accessing Properties
const person = {
name: "Alice",
age: 25,
"favorite color": "blue" // property with space
};
// Dot notation (preferred)
console.log(person.name); // "Alice"
// Bracket notation (for dynamic or special keys)
console.log(person["age"]); // 25
console.log(person["favorite color"]); // "blue"
// Dynamic access
const key = "name";
console.log(person[key]); // "Alice"Adding and Modifying Properties
const person = {
name: "Alice"
};
// Add new property
person.age = 25;
person.city = "NYC";
// Modify existing property
person.name = "Bob";
// Delete property
delete person.city;
console.log(person); // { name: "Bob", age: 25 }Methods
Objects can have functions as properties:
const person = {
name: "Alice",
age: 25,
// Method — function as property
greet: function() {
console.log(`Hi, I'm ${this.name}`);
},
// Shorthand method syntax (modern)
celebrate() {
this.age++;
console.log(`Happy birthday! Now ${this.age}`);
}
};
person.greet(); // "Hi, I'm Alice"
person.celebrate(); // "Happy birthday! Now 26"The this Keyword
this refers to the object the method belongs to:
const user = {
name: "Bob",
greet() {
console.log(`Hello, ${this.name}`);
}
};
user.greet(); // "Hello, Bob"
// Arrow functions don't have their own `this`
const user2 = {
name: "Alice",
greet: () => {
console.log(this.name); // ❌ doesn't work — `this` is not user2
}
};
// Use regular functions for methodsObject Destructuring
Extract properties into variables:
const person = {
name: "Alice",
age: 25,
city: "NYC"
};
// Old way
const name = person.name;
const age = person.age;
// Destructuring
const { name, age, city } = person;
console.log(name); // "Alice"
console.log(age); // 25
// Rename during destructuring
const { name: personName, age: personAge } = person;
console.log(personName); // "Alice"
// Default values
const { name, country = "USA" } = person;
console.log(country); // "USA" (fallback)
// Rest operator
const { name, ...rest } = person;
console.log(rest); // { age: 25, city: "NYC" }Spread Operator
Copy and merge objects:
const person = {
name: "Alice",
age: 25
};
// Copy object
const copy = { ...person };
console.log(copy); // { name: "Alice", age: 25 }
// Merge objects
const details = {
city: "NYC",
country: "USA"
};
const full = { ...person, ...details };
console.log(full);
// { name: "Alice", age: 25, city: "NYC", country: "USA" }
// Override properties
const updated = {
...person,
age: 26,
city: "LA"
};
console.log(updated);
// { name: "Alice", age: 26, city: "LA" }Object Methods
const person = {
name: "Alice",
age: 25,
city: "NYC"
};
// Get all keys
const keys = Object.keys(person);
console.log(keys); // ["name", "age", "city"]
// Get all values
const values = Object.values(person);
console.log(values); // ["Alice", 25, "NYC"]
// Get key-value pairs
const entries = Object.entries(person);
console.log(entries);
// [["name", "Alice"], ["age", 25], ["city", "NYC"]]
// Check if property exists
console.log("name" in person); // true
console.log("email" in person); // false
// hasOwnProperty (safer)
console.log(person.hasOwnProperty("name")); // trueIterating Over Objects
const person = {
name: "Alice",
age: 25,
city: "NYC"
};
// for...in loop
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
// Object.entries with for...of (modern)
for (const [key, value] of Object.entries(person)) {
console.log(`${key}: ${value}`);
}
// Object.keys + forEach
Object.keys(person).forEach((key) => {
console.log(`${key}: ${person[key]}`);
});Nested Objects
Objects can contain other objects:
const user = {
name: "Alice",
address: {
street: "123 Main St",
city: "NYC",
zip: "10001"
},
hobbies: ["reading", "coding"]
};
// Access nested properties
console.log(user.address.city); // "NYC"
console.log(user.hobbies[0]); // "reading"
// Optional chaining — safe access to nested properties
console.log(user.address?.city); // "NYC"
console.log(user.phone?.number); // undefined (no error)
console.log(user.hobbies?.[0]); // "reading"
// Destructuring nested objects
const { address: { city, zip } } = user;
console.log(city); // "NYC"
console.log(zip); // "10001"Computed Property Names
Create properties dynamically:
const key = "name";
const value = "Alice";
// Dynamic property
const person = {
[key]: value
};
console.log(person); // { name: "Alice" }
// With expressions
const prefix = "user";
const obj = {
[`${prefix}Name`]: "Bob",
[`${prefix}Age`]: 30
};
console.log(obj); // { userName: "Bob", userAge: 30 }Shorthand Property Names
If variable name matches property name:
const name = "Alice";
const age = 25;
// Old way
const person = {
name: name,
age: age
};
// Shorthand
const person = {
name,
age
};
console.log(person); // { name: "Alice", age: 25 }Common Patterns
// Merge with defaults
function createUser(options) {
const defaults = {
role: "user",
active: true
};
return { ...defaults, ...options };
}
const user = createUser({ name: "Alice", role: "admin" });
console.log(user);
// { role: "admin", active: true, name: "Alice" }
// Transform object values
const prices = { apple: 1, banana: 2, orange: 3 };
const doubled = Object.fromEntries(
Object.entries(prices).map(([key, value]) => [key, value * 2])
);
console.log(doubled);
// { apple: 2, banana: 4, orange: 6 }
// Filter object properties
const user = {
name: "Alice",
password: "secret",
email: "alice@example.com"
};
const safe = Object.fromEntries(
Object.entries(user).filter(([key]) => key !== "password")
);
console.log(safe);
// { name: "Alice", email: "alice@example.com" }Key Takeaways
- Objects store key-value pairs
- Use dot notation when possible, bracket notation for dynamic access
- Methods are functions stored as object properties
- Use regular functions for methods (not arrow functions) to access
this - Spread operator (
...) copies and merges objects - Destructuring extracts properties into variables
Object.keys(),Object.values(),Object.entries()help iterate over objects- Optional chaining (
?.) safely accesses nested properties