Objects
An object is a filled-in form: every box has a label, and every label has an answer.
An array is great for a list of similar things. But how would you describe a single product? It has a name, a price, a stock count, whether it's vegan. You could put those in an array, ['Sourdough', 8, 12, true], but then what does [2] mean? You'd need to memorize that the third slot is the stock count.
There's a better way: give each value a label.
A labeled form
Picture a paper form: "Name: ______. Price: ______. In stock: ______." Every answer sits next to a label that says what it means. That's an object:
const bread = {
name: 'Sourdough',
price: 8,
stock: 12,
isVegan: true,
};- Curly braces make an object.
- Each line is a property: a key (the label), a colon, and a value (the answer).
- Properties are separated by commas. A comma after the last one is allowed, and makes adding a new line later tidier.
Values can be anything: strings, numbers, booleans, arrays, even other objects.
Reading properties
Dot notation, the everyday way:
console.log(bread.name); // 'Sourdough'
console.log(bread.price); // 8Bracket notation, with the key as a string:
console.log(bread['name']); // 'Sourdough'Why have two? Brackets let you use a key that's stored in a variable:
const field = 'stock';
console.log(bread[field]); // 12
console.log(bread.field); // undefined: looks for a key literally named "field"Use dots whenever you know the key while writing the code. Use brackets when the key comes from a variable. Asking for a key that doesn't exist gives undefined, not an error.
Changing, adding, and removing
bread.price = 9; // change an existing property
bread.bakedAt = '6am'; // add a new one
delete bread.isVegan; // remove oneJust like arrays, an object stored in a const can have its properties changed. const only stops you from replacing the whole object.
Objects inside objects
Real data is usually nested:
const order = {
id: 1042,
customer: {
name: 'Ana',
email: 'ana@example.com',
},
items: ['Sourdough', 'Coffee'],
};
console.log(order.customer.name); // 'Ana'
console.log(order.items[1]); // 'Coffee'Read the dots left to right, one step deeper each time: "the order's customer's name."
Safe digging with ?.
What if the customer is missing?
const walkIn = { id: 1043, items: ['Rye'] };
console.log(walkIn.customer.name);
// TypeError: Cannot read properties of undefined (reading 'name')walkIn.customer is undefined, and you can't read a property of undefined. This is one of the most common errors in JavaScript. The optional chaining operator ?. stops early instead of crashing:
console.log(walkIn.customer?.name); // undefined, no errorRead ?. as "and if that exists, then..." It pairs beautifully with ?? from Operators and Comparisons:
const displayName = walkIn.customer?.name ?? 'Guest';Use it where something is genuinely optional. Don't scatter it everywhere: if a value should always exist, a loud error helps you find the real bug.
Methods: functions that belong to an object
A property can hold a function. Then it's called a method:
const bakery = {
name: "Maria's Bakery",
openHour: 7,
isOpenAt(hour) {
return hour >= this.openHour && hour < 17;
},
};
console.log(bakery.isOpenAt(9)); // trueYou've been using methods all along: console.log is the log method of the console object, and push is a method of every array.
That this means "the object this method was called on," so this.openHour is the bakery's openHour. this has some surprising behavior, and it gets a full lesson in this and Classes.
Looping over an object
Three built-in helpers turn an object into arrays you can loop over:
const stock = { sourdough: 12, rye: 0, focaccia: 5 };
console.log(Object.keys(stock)); // ['sourdough', 'rye', 'focaccia']
console.log(Object.values(stock)); // [12, 0, 5]
for (const [bread, count] of Object.entries(stock)) {
console.log(`${bread}: ${count}`);
}Object.entries gives you pairs of [key, value]. The [bread, count] part unpacks each pair into two variables, a trick called destructuring that's coming up in Destructuring and Spread.
To check whether a key exists, use Object.hasOwn(stock, 'rye') or 'rye' in stock. Don't just check if (stock.rye): a stock of 0 is falsy, and you'd wrongly conclude rye isn't on the list at all.
Arrays of objects
Most real data looks like this, a list of labeled forms:
const products = [
{ name: 'Sourdough', price: 8 },
{ name: 'Rye', price: 7 },
];That's exactly the shape you worked with in Array Methods, and it's the shape you'll get from almost every server you ever load data from.
Comparing objects
One more surprise, related to the sharing surprise from Arrays:
const a = { name: 'Rye' };
const b = { name: 'Rye' };
console.log(a === b); // false
console.log(a === a); // true=== on objects doesn't compare their contents. It asks "are these the same object?" Two forms with identical answers written on them are still two separate pieces of paper. To compare contents, compare the properties you care about: a.name === b.name.
Try it
HTML
JavaScript
Preview
Console
Nothing logged yet. Anything you pass to console.log() shows up here.
Try it yourself
- Add a
categoryproperty with the value'Loaves', and show it in the card's details. - Delete
isVeganwithdelete, and see how the details line handles the missing value. - Remove the
?.from thewalkInline and read the error. Then put it back.
Check your understanding
Up next
You've seen [bread, count] pull two values out of a pair, and [...prices] copy an array. Those are two of the most popular modern shortcuts in JavaScript. Next up: Destructuring and Spread.
