JavaScript Objects
Objects are one of the most important data types in JavaScript. They allow you to store collections of related data and functionality together using key-value pairs.
Try It Yourself
Experiment with creating and manipulating objects:
// JavaScript Objects - try modifying this code!
// Creating an object
const person = {
name: "Alice",
age: 28,
city: "New York",
hobbies: ["reading", "coding", "hiking"],
greet: function() {
return "Hello, I'm " + this.name + "!";
}
};
// Accessing properties
console.log("Name:", person.name);
console.log("Age:", person["age"]);
console.log("First hobby:", person.hobbies[0]);
// Calling a method
console.log(person.greet());
// Modifying properties
person.age = 29;
person.country = "USA"; // Adding new property
console.log("\nUpdated object:");
console.log(person);
// Object methods
console.log("\nKeys:", Object.keys(person));
console.log("Values:", Object.values(person));Creating Objects
The most common way to create an object is using object literal syntax with curly braces:
// Object literal syntax - most common way
const person = {
firstName: "John",
lastName: "Doe",
age: 30,
isEmployed: true
};
// Empty object
const emptyObj = {};
// Object with various value types
const mixed = {
text: "Hello", // String
number: 42, // Number
active: true, // Boolean
nothing: null, // Null
items: [1, 2, 3], // Array
nested: { a: 1, b: 2 }, // Nested object
greet: function() { // Function (method)
return "Hi!";
}
};Accessing Properties
You can access object properties using dot notation or bracket notation:
const car = {
brand: "Toyota",
model: "Camry",
year: 2023,
"fuel type": "Hybrid" // Key with space
};
// Dot notation - clean and common
console.log(car.brand); // "Toyota"
console.log(car.model); // "Camry"
// Bracket notation - flexible
console.log(car["year"]); // 2023
console.log(car["fuel type"]); // "Hybrid" (required for spaces)
// Dynamic property access
const prop = "brand";
console.log(car[prop]); // "Toyota" (using variable)
// Accessing undefined property
console.log(car.color); // undefined (no error)| Feature | Dot Notation | Bracket Notation |
|---|---|---|
| Syntax | obj.property | obj["property"] |
| Dynamic keys | ||
| Spaces in keys | ||
| Special characters | ||
| Readability | Better | Good |
| Use case | Known property names | Variable/computed names |
Modifying Objects
Objects are mutable - you can add, update, and delete properties:
const user = {
name: "Alice",
age: 25
};
// Updating existing properties
user.age = 26;
user["name"] = "Alice Smith";
// Adding new properties
user.email = "alice@example.com";
user["phone"] = "555-1234";
// Deleting properties
delete user.phone;
console.log(user);
// { name: "Alice Smith", age: 26, email: "alice@example.com" }
// Check if property exists
console.log("email" in user); // true
console.log("phone" in user); // false
console.log(user.hasOwnProperty("name")); // trueES6 Shorthand Syntax
ES6 introduced cleaner ways to define object properties and methods:
// Property shorthand (ES6)
const name = "Bob";
const age = 30;
// Old way
const person1 = { name: name, age: age };
// Shorthand - when variable name matches property name
const person2 = { name, age };
console.log(person2); // { name: "Bob", age: 30 }
// Method shorthand (ES6)
const calculator = {
// Old way
add: function(a, b) {
return a + b;
},
// Shorthand
subtract(a, b) {
return a - b;
}
};
// Computed property names (ES6)
const propName = "score";
const game = {
[propName]: 100,
["player" + 1]: "Alice"
};
console.log(game); // { score: 100, player1: "Alice" }Nested Objects
Objects can contain other objects, creating nested structures:
const company = {
name: "TechCorp",
address: {
street: "123 Main St",
city: "San Francisco",
country: "USA"
},
employees: [
{ name: "Alice", role: "Developer" },
{ name: "Bob", role: "Designer" }
]
};
// Accessing nested properties
console.log(company.address.city); // "San Francisco"
console.log(company.employees[0].name); // "Alice"
// Safe access with optional chaining (?.)
console.log(company.address?.zipCode); // undefined (no error)
console.log(company.ceo?.name); // undefined (no error)
// Modifying nested properties
company.address.zipCode = "94102";
company.employees.push({ name: "Carol", role: "Manager" });Iterating Over Objects
There are several ways to loop through an object's properties:
const product = {
name: "Laptop",
price: 999,
inStock: true
};
// for...in loop
console.log("--- for...in ---");
for (const key in product) {
console.log(key + ": " + product[key]);
}
// Object.keys() - array of keys
console.log("\nKeys:", Object.keys(product));
// ["name", "price", "inStock"]
// Object.values() - array of values
console.log("Values:", Object.values(product));
// ["Laptop", 999, true]
// Object.entries() - array of [key, value] pairs
console.log("Entries:", Object.entries(product));
// [["name", "Laptop"], ["price", 999], ["inStock", true]]
// Iterating with forEach
Object.entries(product).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});Object Destructuring
Destructuring allows you to extract properties into variables with a concise syntax:
const person = {
name: "Alice",
age: 28,
city: "NYC",
country: "USA"
};
// Basic destructuring
const { name, age } = person;
console.log(name); // "Alice"
console.log(age); // 28
// Renaming variables
const { city: location } = person;
console.log(location); // "NYC"
// Default values
const { phone = "N/A" } = person;
console.log(phone); // "N/A"
// Rest operator
const { name: userName, ...rest } = person;
console.log(userName); // "Alice"
console.log(rest); // { age: 28, city: "NYC", country: "USA" }
// Nested destructuring
const company = {
info: { name: "TechCorp", founded: 2020 }
};
const { info: { name: companyName } } = company;
console.log(companyName); // "TechCorp"Spread Operator
The spread operator (...) is useful for copying and merging objects:
// Copying objects (shallow copy)
const original = { a: 1, b: 2 };
const copy = { ...original };
console.log(copy); // { a: 1, b: 2 }
// Merging objects
const defaults = { theme: "dark", lang: "en" };
const userPrefs = { theme: "light" };
const settings = { ...defaults, ...userPrefs };
console.log(settings); // { theme: "light", lang: "en" }
// Adding/overriding properties
const user = { name: "Alice", age: 25 };
const updatedUser = { ...user, age: 26, city: "NYC" };
console.log(updatedUser);
// { name: "Alice", age: 26, city: "NYC" }
// Note: Spread creates a SHALLOW copy
const nested = { a: { b: 1 } };
const shallowCopy = { ...nested };
shallowCopy.a.b = 99;
console.log(nested.a.b); // 99 (original also changed!)Built-in Object Methods
JavaScript provides many useful static methods on the Object constructor:
const obj = { a: 1, b: 2, c: 3 };
// Object.keys() - get all keys
console.log(Object.keys(obj)); // ["a", "b", "c"]
// Object.values() - get all values
console.log(Object.values(obj)); // [1, 2, 3]
// Object.entries() - get [key, value] pairs
console.log(Object.entries(obj)); // [["a", 1], ["b", 2], ["c", 3]]
// Object.assign() - copy/merge objects
const target = { x: 1 };
const source = { y: 2 };
Object.assign(target, source);
console.log(target); // { x: 1, y: 2 }
// Object.freeze() - prevent modifications
const frozen = Object.freeze({ name: "Alice" });
frozen.name = "Bob"; // Silently fails (or error in strict mode)
console.log(frozen.name); // "Alice"
// Object.seal() - prevent adding/removing (but can modify)
const sealed = Object.seal({ name: "Alice" });
sealed.name = "Bob"; // Works
sealed.age = 25; // Fails
console.log(sealed); // { name: "Bob" }
// Object.fromEntries() - create object from entries
const entries = [["a", 1], ["b", 2]];
console.log(Object.fromEntries(entries)); // { a: 1, b: 2 }Test Your Knowledge
JavaScript Objects Quiz
5 questionsHow do you access a property with a space in its name?
What does Object.keys(obj) return?
What is the output of: const { a = 5 } = { b: 10 }; console.log(a);
What does the spread operator (...) do with objects?
How do you check if an object has a specific property?
Coding Challenge
Create a function that deeply merges two objects. Unlike the spread operator which only does a shallow merge, your function should recursively merge nested objects.
// Challenge: Create a function that merges two objects deeply
// Unlike spread (...) which does shallow merge, this should merge nested objects
function deepMerge(target, source) {
// Your code here
// Hint: Check if values are objects, then recursively merge
}
// Test cases
const obj1 = {
name: "Product",
details: {
price: 100,
stock: 50
},
tags: ["sale"]
};
const obj2 = {
details: {
price: 80,
discount: true
},
tags: ["featured"],
active: true
};
const result = deepMerge(obj1, obj2);
console.log(result);
// Expected:
// {
// name: "Product",
// details: { price: 80, stock: 50, discount: true },
// tags: ["featured"],
// active: true
// }Summary
- Objects store data as key-value pairs using curly braces
{} - Access properties with dot notation (
obj.key) or bracket notation (obj["key"]) - Objects are mutable - you can add, update, and delete properties
- Destructuring extracts properties into variables:
const {'{'} name {'}'} = obj - The spread operator (
...) copies and merges objects (shallow copy) - Use Object.keys(), Object.values(), and Object.entries() to iterate over objects
- Optional chaining (
?.) safely accesses nested properties