Lesson 8 of 12

JavaScript Objects

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 left

JavaScript 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

Key takeaways

  • An object groups related values as key: value properties inside { }.
  • Use dot notation normally; use brackets for keys in variables or with special characters.
  • A function stored in a property is a method; this refers to the object it was called on.
  • Object.keys, Object.values and Object.entries let you loop over an object.
  • Assigning an object copies the reference – use { ...obj } or structuredClone() for a copy.
  • JSON.stringify and JSON.parse convert between objects and JSON text.

Quick quiz

Check what you learned – pick an answer.

1. Given const key = 'city'; which expression reads user.city using the variable?

2. What does Object.keys({ a: 1, b: 2 }) return?

3. After const b = a; b.price = 99; what is a.price?

Practice exercise

Create an object called student with the properties name, rollNo and marks (an array of three numbers), plus a method average() that returns the average of the marks. Show the student's name and average on the page.

Show a hint

Inside the method, use this.marks with reduce(), then divide by this.marks.length.

Show the solution
<p id="out"></p>
<script>
  const student = {
    name: 'Nandhini',
    rollNo: 23,
    marks: [78, 85, 92],
    average() {
      return this.marks.reduce((sum, m) => sum + m, 0) / this.marks.length;
    }
  };

  document.getElementById('out').textContent =
    `${student.name} (roll no. ${student.rollNo}) – average: ${student.average().toFixed(1)}`;
</script>

Progress is saved in this browser only.