Topic 3: JavaScript Objects
📖 6 min read · 🎯 beginner · 🧭 Prerequisites: element-design-based-on-the-picture-requirement, iframe-embed-albums-embed-video-embed-maps-input-tag-introduction
Why this matters
Here's the thing — up until now, you've been storing one value in one variable. A name here, a number there. But real data doesn't work that way. A user on a website has a name, an email, an age, a profile picture — all belonging to the same person. How do you keep all that together? That's exactly what a JavaScript object solves. Instead of five separate variables, you get one tidy bundle where every piece of information has a label. Once you understand objects, you can model anything — a product, a form, a user, a course — in JavaScript.
What You'll Learn
- Create objects using three different syntaxes: literals,
new Object(), and constructor functions - Access and modify object properties with dot notation and bracket notation
- Add, delete, and dynamically manage properties on any object
- Write object methods and use the
thiskeyword correctly - Loop through properties with
for...in, destructure objects, and work with nested structures - Clone and merge objects using the spread operator and
Object.assign()
The Analogy
Think of a JavaScript object as a filing cabinet drawer labeled with a person's name. Inside the drawer are labeled folders — name, age, city — each holding a single piece of information. You can open any folder by name, replace its contents, add a new folder, or even toss one out. You can also slip an entire set of instructions (a method) into one of those folders, so the cabinet knows how to introduce itself. Nested objects are just drawers-within-drawers: a folder labeled address that itself contains street, city, and country folders.
Chapter 1: What Is an Object?
In JavaScript, an object is a collection of properties, where each property is a key-value pair. Objects group related data and functionality together under one roof.
There are three common ways to create an object.
1. Object Literal Syntax — the shortest and most common approach:
let person = {
name: "Alice",
age: 25,
city: "Vizag"
};
2. Using new Object() Syntax — adds properties one at a time after creation:
let person = new Object();
person.name = "Alice";
person.age = 25;
person.city = "Vizag";
3. Using a Constructor Function — a blueprint for creating many similar objects:
function Person(name, age, city) {
this.name = name;
this.age = age;
this.city = city;
}
let person = new Person("Alice", 25, "Vizag");
Constructor functions are named with a capital letter by convention, signaling that they're meant to be called with new.
Chapter 2: Accessing and Modifying Object Properties
Once an object exists, you can read or change its properties in two ways.
Dot Notation — clean and readable when the property name is a valid identifier:
let person = {
name: "Alice",
age: 25,
city: "Vizag"
};
console.log(person.name); // Output: Alice
console.log(person.age); // Output: 25
person.age = 26;
console.log(person.age); // Output: 26
Bracket Notation — required when the property name is dynamic, stored in a variable, or contains special characters:
console.log(person["name"]); // Output: Alice
console.log(person["age"]); // Output: 25
person["city"] = "CoderTown";
console.log(person.city); // Output: CoderTown
Both notations read and write the same underlying data — they're interchangeable for standard identifiers.
Chapter 3: Adding and Deleting Properties
Objects in JavaScript are dynamic: you can add or remove properties at any time after creation.
Adding Properties — simply assign to a key that doesn't exist yet:
person.country = "Wonderland";
console.log(person.country); // Output: Wonderland
Deleting Properties — use the delete operator; the property becomes undefined afterwards:
delete person.city;
console.log(person.city); // Output: undefined
This flexibility makes objects ideal for building up data incrementally as your program runs.
Chapter 4: Object Methods
A method is a function stored as a property of an object. Methods let the object carry its own behavior alongside its data.
let person = {
name: "Alice",
age: 25,
city: "Vizag",
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
person.greet(); // Output: Hello, my name is Alice
Inside a method, this refers to the object that owns the method — so this.name resolves to "Alice" here.
Chapter 5: Looping Through Object Properties
The for...in loop iterates over every enumerable property key in an object. Use hasOwnProperty() to skip inherited properties:
for (let key in person) {
if (person.hasOwnProperty(key)) {
console.log(key + ": " + person[key]);
}
}
This pattern is useful for inspecting, serializing, or transforming every field of an object without knowing its keys in advance.
Chapter 6: Nested Objects
Objects can contain other objects as property values, enabling arbitrarily deep data structures.
let person = {
name: "Alice",
age: 25,
address: {
street: "123 Main St",
city: "Vizag",
country: "Wonderland"
}
};
console.log(person.address.city); // Output: Vizag
Chain dot notation (or bracket notation) to drill into nested levels: person.address.city reads the city key inside the address object inside person.
Chapter 7: Object Destructuring
Destructuring extracts properties from an object into individual variables in a single, readable line.
let person = {
name: "Alice",
age: 25,
city: "Vizag"
};
let { name, age, city } = person;
console.log(name); // Output: Alice
console.log(age); // Output: 25
console.log(city); // Output: Vizag
The variable names on the left must match the property keys on the right. You can also rename during destructuring: let { name: fullName } = person stores "Alice" in fullName.
Chapter 8: Object Methods and the this Keyword
The this keyword inside a method always refers to the object the method was called on, making it possible to both read and mutate the object's own data.
let person = {
name: "Alice",
age: 25,
greet: function() {
console.log("Hello, my name is " + this.name);
},
updateAge: function(newAge) {
this.age = newAge;
}
};
person.greet(); // Output: Hello, my name is Alice
person.updateAge(26);
console.log(person.age); // Output: 26
updateAge uses this.age to write directly to the object that called it — no external references needed.
Chapter 9: Practical Example — Managing a Book Collection
Here the class ties everything together by building and displaying a collection of books using an array of objects.
let book1 = {
title: "JavaScript: The Good Parts",
author: "Douglas Crockford",
year: 2008
};
let book2 = {
title: "Eloquent JavaScript",
author: "Marijn Haverbeke",
year: 2018
};
let bookCollection = [book1, book2];
// Adding a new book to the collection
let book3 = {
title: "You Don't Know JS",
author: "Kyle Simpson",
year: 2015
};
bookCollection.push(book3);
// Displaying the book collection
bookCollection.forEach(book => {
console.log(`${book.title} by ${book.author} (${book.year})`);
});
Expected output:
JavaScript: The Good Parts by Douglas Crockford (2008)
Eloquent JavaScript by Marijn Haverbeke (2018)
You Don't Know JS by Kyle Simpson (2015)
Each book is an object; the collection is an array of those objects — a very common real-world pattern.
Chapter 10: Cloning and Merging Objects
Because objects are reference types in JavaScript, assigning one object variable to another just copies the reference — both variables point to the same data. To get a true independent copy, clone it.
Cloning an Object — using the spread operator or Object.assign():
let person = {
name: "Alice",
age: 25
};
// Using the spread operator
let clone1 = { ...person };
console.log(clone1); // { name: 'Alice', age: 25 }
// Using Object.assign()
let clone2 = Object.assign({}, person);
console.log(clone2); // { name: 'Alice', age: 25 }
Merging Objects — combine two or more objects into one, again using spread or Object.assign():
let person = {
name: "Alice",
age: 25
};
let address = {
city: "Vizag",
country: "Wonderland"
};
// Using the spread operator
let merged1 = { ...person, ...address };
console.log(merged1);
// { name: 'Alice', age: 25, city: 'Vizag', country: 'Wonderland' }
// Using Object.assign()
let merged2 = Object.assign({}, person, address);
console.log(merged2);
// { name: 'Alice', age: 25, city: 'Vizag', country: 'Wonderland' }
When keys conflict, the last source wins. Both spread and Object.assign() produce shallow copies — nested objects are still shared references.
🧪 Try It Yourself
Task: Build a student object that tracks a student's name, grade level, and three favorite subjects. Then write a method called introduce() that prints a sentence like "Hi, I'm Alice, a grade-10 student who loves Math, Art, and Science." Finally, destructure the object to pull out name and grade into separate variables and log them.
Success criterion: Running the script should print the introduction sentence, then two separate lines for name and grade.
Starter snippet:
let student = {
name: "Alice",
grade: 10,
subjects: ["Math", "Art", "Science"],
introduce: function() {
// your code here
}
};
student.introduce();
let { name, grade } = student;
console.log(name);
console.log(grade);
🔍 Checkpoint Quiz
Q1. What is the difference between dot notation (person.name) and bracket notation (person["name"]), and when would you be forced to use bracket notation?
Q2. Given this code, what does it log?
let car = {
brand: "Toyota",
year: 2020,
describe: function() {
console.log(this.brand + " " + this.year);
}
};
car.year = 2023;
car.describe();
A) Toyota 2020
B) Toyota 2023
C) undefined 2023
D) An error is thrown
Q3. What is wrong with the following code?
let obj = { color: "blue", size: 10 };
let copy = obj;
copy.color = "red";
console.log(obj.color);
A) copy is not valid syntax
B) obj.color is still "blue" because objects are immutable
C) obj.color is now "red" because copy is a reference, not a clone
D) console.log cannot print object properties
Q4. You have two objects, defaults (with keys theme, language, fontSize) and userPrefs (with keys theme and fontSize). How would you merge them so that userPrefs values override defaults for any shared keys?
A1. Both notations access the same property. Bracket notation is required when the key is stored in a variable (e.g., person[keyVar]), contains spaces or special characters (e.g., obj["first-name"]), or is computed at runtime. Dot notation requires a valid, static identifier.
A2. B) Toyota 2023 — car.year is updated to 2023 before describe() is called, and this.brand resolves to "Toyota".
A3. C) obj.color is now "red" — let copy = obj copies the reference, not the data. Both copy and obj point to the same object in memory, so mutating copy mutates obj. Use let copy = { ...obj } to get an independent clone.
A4. Place userPrefs after defaults so its keys win: let settings = { ...defaults, ...userPrefs }; — or equivalently Object.assign({}, defaults, userPrefs). Properties from later sources overwrite earlier ones on key collision.
🪞 Recap
- A JavaScript object is a collection of key-value pairs that groups related data and behavior together.
- Properties can be read and written with dot notation or bracket notation, added on the fly, and removed with
delete. - Methods are functions stored as object properties; inside them,
thisrefers to the owning object. for...inloops over all enumerable keys; destructuring unpacks properties into named variables in one line.- Nested objects let you model complex, hierarchical data (e.g., a
personwith anaddresssub-object). - Use the spread operator (
{ ...obj }) orObject.assign()to clone or merge objects without sharing references.
📚 Further Reading
- MDN — Working with Objects — the source of truth on JavaScript object mechanics
- MDN — Destructuring Assignment — full syntax reference including renaming and default values
- Eloquent JavaScript, Chapter 4: Data Structures — Marijn Haverbeke's free in-depth treatment of objects and arrays
- ⬅️ Previous: iFrame, Embed, Albums, Video, Maps & Input Tag Introduction
- ➡️ Next: Div Positioning