Module 1 · Foundations & First Steps ⏱ 18 min

Objects — Grouping Related Data

By the end of this lesson you will be able to:
  • Create objects with key/value properties
  • Read and update properties with dot and bracket notation
  • List keys and values with Object.keys and Object.values

An object groups related data as key/value pairs — a way to keep everything about one thing together under a single name. You write it as a literal inside curly braces:

const book = {
  title: "Dune",
  pages: 412,
  read: false
};
console.log(book.title);   // "Dune"

Each key is a string (quotes optional when it is a valid identifier), followed by a colon and its value. Read or change a value with dot notation (book.title), and you can attach a property that did not exist yet by simply assigning to it:

book.author = "Frank Herbert";
book.read = true;

After this, book holds four properties; none had to be declared ahead of time. Asking for a key that is not there is not an error — book.publisher is simply undefined.

flowchart TD
  O["book object"] --> K1["title: Dune"]
  O --> K2["pages: 412"]
  O --> K3["read: false"]
  style O fill:#e0900b,color:#fff
An object maps each key to a value; reach a value through its key.

Bracket notation and listing keys

Dot notation is the everyday choice, but it only works when the key is a literal, valid identifier. When the key lives in a variable, or contains spaces or characters an identifier cannot, use bracket notation:

const scores = { math: 90, science: 85, art: 78 };
const subject = "science";
console.log(scores[subject]);   // 85
console.log(scores["art"]);      // 78

Notice scores.subject would hunt for a property literally named subject and return undefined; brackets are how you say "use the value of this variable as the key". To see what an object holds, Object.keys lists its key names and Object.values lists the values. Both return arrays, which is why you can loop over them — and for a plain literal that means every key you wrote.

const scores = { math: 90, science: 85, art: 78 };
console.log(Object.keys(scores));
console.log(Object.values(scores));

let total = 0;
for (const subject of Object.keys(scores)) {
  total += scores[subject];   // bracket access with a variable key
}
console.log(total);
flowchart TD
  Q{"Key known and<br/>a valid identifier?"} -->|Yes| D["use dot: obj.key"]
  Q -->|No, or dynamic| B["use brackets: obj key"]
  style D fill:#1e7f3d,color:#fff
  style B fill:#b45309,color:#fff
Use dot for a known key; use brackets when the key is dynamic or not a valid identifier.

Nesting, mutation, and removal

Values inside an object are not stuck where you first put them. You reassign them at any time, and a value can itself be another object — which is how you model nested shapes like an order that contains an item. Reach a nested value by chaining dot accesses, walking one level at a time: order.item.name.

Removing a key uses the delete operator: delete order.item.price drops the price property entirely, rather than blanking it to undefined. Deletion is destructive, so reach for it deliberately — the immutable alternative is to build a fresh object with spread and leave the original untouched.

Objects nest, mutate, and lose keys through delete.
const user = { name: "Ada", stats: { score: 10, level: 1 } };
console.log(user.stats.score);
user.stats.score = 25;
console.log(user.stats.score);
delete user.stats.level;
console.log(Object.keys(user.stats));
flowchart LR
  A["const a = obj"] --> O["one object in memory"]
  B["const b = a"] --> O
  O -.->|"change via b<br/>is visible through a"| A
  style O fill:#b91c1c,color:#fff
Assigning an object shares it — both names point at the same data.

Objects are shared, not copied

Here is the trap that bites every JavaScript learner. Assigning a number copies it — after let b = a, changing b leaves a alone. Objects do not behave that way. After const b = a where a is an object, b is not a second copy; it is a second name for the very same object in memory. Change a property through b and a sees the change too, because there was only ever one object.

This is why a function that mutates an object argument can quietly change its caller's original. To make a genuine, independent copy, spread into a new object: { ...a }. Then the two can drift apart without interfering.

Methods: functions as property values

Because a function is just a value, you can store one as a property. A function that lives on an object is called a method, and you call it with dot notation, exactly like reading any other value: counter.bump().

Inside a method, the keyword this refers to the object the method was called on, so this.count += 1 updates that object's own count. Methods are how objects gain behavior, not just data. A later lesson digs into this and the rules that make it subtle; for now, read this as "the object to the left of the dot".

A function stored as a property becomes a method; call it with dot.
const counter = {
  count: 0,
  bump() { this.count += 1; }
};
counter.bump();
counter.bump();
console.log(counter.count);
Exercise

What does this print? We read one property, then list every key.

const user = { name: "Ada", age: 30 };
console.log(user.name);
console.log(Object.keys(user));
Exercise

Write totalAge(people) where people is an array of objects like {age: 10}. Return the sum of every person's age.

function totalAge(people) {
  // return the sum of all ages
}
Exercise

Write totalValues(obj) that returns the sum of every value in obj (assume each value is a number). Iterate with Object.values.

function totalValues(obj) {
  // return the sum of all values
}
Exercise

This tries to return a profile with a new city while leaving the caller's original alone. It fails: const copy = profile makes copy another name for the same object, so setting copy.city also changes the original profile. Make the copy independent with object spread.

function withNewCity(profile) {
  const copy = profile;
  copy.city = "Lagos";
  return copy;
}
Exercise

What does this print? Reach a nested value through two dot accesses, then remove a key and list what remains.

const order = { id: 7, item: { name: "Book", price: 12 } };
console.log(order.item.name);
delete order.item.price;
console.log(Object.keys(order.item));

Recap

  • An object is a bundle of key/value pairs written in {}; reach a value with dot (obj.key) or bracket (obj[key]) notation.
  • Reach for brackets when the key lives in a variable or is not a valid identifier; dot needs a literal name.
  • Object.keys and Object.values return arrays of the names and the values, ready to loop over.
  • Properties are mutable: assign to add or change, delete to remove, and chain dots to reach nested data.
  • Assigning an object shares it — both names see the same data, so a real copy needs spread.

Next you'll learn how arrays hold ordered lists of values and the methods that make them powerful.

Checkpoint quiz

How do you read the name property of an object stored in user?

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

Go deeper — technical resources