An array is great for a list of similar things, but how would you store everything about one thing – a product’s name, price, stock and category? Keeping four separate variables quickly gets messy. An object groups related values under one name, with each value labelled by a key. JavaScript objects are the most important data structure in the language: the page itself, every element on it and every response from a server is handled as an object.
Creating an object
The easiest way is an object literal: curly braces containing key: value pairs separated by commas. Each pair is called a property. Keys are usually written like variable names; values can be any type, including arrays and other objects.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Objects</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
</style>
</head>
<body>
<pre id="out"></pre>
<script>
const product = {
name: 'Cotton saree',
price: 1850,
inStock: true,
colours: ['maroon', 'mustard', 'teal'],
seller: {
shop: 'Lotus Handlooms',
city: 'Kanchipuram'
}
};
// Dot notation
const line1 = `${product.name} – Rs. ${product.price}`;
// Bracket notation (key as a string)
const line2 = `In stock: ${product['inStock']}`;
// Nested values
const line3 = `Sold by ${product.seller.shop}, ${product.seller.city}`;
const line4 = `First colour: ${product.colours[0]}`;
document.getElementById('out').textContent =
[line1, line2, line3, line4].join('\n');
</script>
</body>
</html>Dot notation vs bracket notation
Dot notation (product.price) is short and readable, so use it most of the time. Bracket notation (product['price']) is needed in two situations:
- When the key is stored in a variable:
const field = 'price'; product[field]. - When the key is not a valid identifier, for example it contains a space or a hyphen:
order['delivery-date'].
Reading a property that does not exist gives undefined rather than an error. But trying to read a property of undefined – such as product.discount.amount when there is no discount – throws a TypeError. The optional chaining operator ?. solves this, as you will see in Modern JavaScript (ES6+).
Adding, changing and deleting properties
JavaScript objects are flexible. Assign to a new key to add it, assign to an existing key to update it, and use delete to remove one. As with arrays, an object declared with const can still have its properties changed – const only protects the name from pointing to a different object.
const user = { name: 'Divya', city: 'Hosur' };
user.email = '[email protected]'; // add
user.city = 'Bengaluru'; // update
delete user.email; // remove
// user is now { name: 'Divya', city: 'Bengaluru' }Methods and this
When a property holds a function, it is called a method. Inside a method, the keyword this refers to the object the method was called on, so the method can read the object’s other properties. You have used methods all along: document.getElementById() is a method of the document object, and push() is a method of arrays.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Methods</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
</style>
</head>
<body>
<pre id="out"></pre>
<script>
const cart = {
owner: 'Rahul',
items: [],
add(name, price, qty = 1) {
this.items.push({ name, price, qty });
},
total() {
return this.items.reduce((sum, item) => sum + item.price * item.qty, 0);
}
};
cart.add('Basmati rice 5 kg', 649);
cart.add('Toor dal 1 kg', 165, 2);
cart.add('Ghee 500 ml', 340);
let text = `Cart for ${cart.owner}\n`;
for (const item of cart.items) {
text += `- ${item.name} x ${item.qty} = Rs. ${item.price * item.qty}\n`;
}
text += `Total: Rs. ${cart.total()}`;
document.getElementById('out').textContent = text;
</script>
</body>
</html>Two modern shortcuts appear here. add(name, price) { … } is the short method syntax. And { name, price, qty } is shorthand for { name: name, price: price, qty: qty } when the variable and key share a name.
Watch out: Do not write methods as arrow functions if they use this. Arrow functions do not get their own this, so this.items inside one would not refer to the cart. Use the short method syntax shown above.
Looping over an object
Objects are not lists, so for…of does not work on them directly. Instead, turn them into arrays with Object.keys(obj) (the keys), Object.values(obj) (the values) or Object.entries(obj) (pairs of [key, value]), and loop over those. The older for…in loop also visits each key.
const stock = { idli: 40, dosa: 25, vada: 60 };
for (const [item, count] of Object.entries(stock)) {
console.log(`${item}: ${count} left`);
}
// idli: 40 left, dosa: 25 left, vada: 60 leftJavaScript objects are copied by reference
Writing const copy = original; does not create a second object. Both names point to the same one, so changing copy.price also changes original.price. To make an independent copy, use the spread syntax { ...original } for a shallow copy, or structuredClone(original) to copy nested objects and arrays too. Comparing two different objects with === is always false, even if their contents look identical.
JSON: objects as text
JSON (JavaScript Object Notation) is a text format based on object literal syntax, and it is how most web servers send data. JSON.stringify(obj) turns an object into a JSON string, for example to save it in localStorage; JSON.parse(text) turns a JSON string back into an object. In JSON, keys must be in double quotes and functions are not allowed. You will parse real JSON responses in Fetch and Async JavaScript.
Now that you can store data in arrays and objects, the next step is to show it on the page. That is the job of the DOM, covered in JavaScript DOM Manipulation.
Further reading
- developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_objects
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
- developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON
