Just JavaScript· 07
Chapter 07 · Objects, in depth

Properties

Properties are wires too — but they start from objects, not from your code. Reading obj.prop is a question JavaScript answers with a short, mechanical procedure. Learn the rules and even sherlock.boat.name stops being a mystery. Meet Sherlock Holmes.

Sherlock Holmes lives at a London address. His friend John Watson moves in, then changes his name and leaves for Malibu:

let sherlock = {
  surname: 'Holmes',
  address: { city: 'London' }
};
let john = {
  surname: 'Watson',
  address: sherlock.address
};
john.surname = 'Lennon';
john.address.city = 'Malibu';

Surprisingly, after this runs sherlock.address.city is also "Malibu" — it's not easy to get away from Sherlock. To see why, we first need the rules for how properties work. We'll fully solve the Malibu mystery in Chapter 08. For now, a simpler object: { surname: 'Holmes', age: 64 }.

Lab · walk the rules

How JavaScript answers obj.prop, step by step

Pick an expression and step through it. Watch JavaScript follow the sherlock wire, look for the property, and either hand back a value, fall through to undefined, or throw. The diagram lights up the wire it's on.

Step 0 / 0 — press Step to begin
ReadyChoose an expression, then walk it one rule at a time.
console.log(sherlock.age)
01

Properties are wires from objects

A variable's wire starts in your code. A property's wire starts from an object. Both always point at values — they never contain them.

let sherlock = {
  surname: 'Holmes',
  age: 64,
};

Here sherlock is a variable, but surname and age are properties — they belong to a particular object. The sherlock wire points at an object; that object's surname wire points at "Holmes" and its age wire points at 64.

Think in wires, not nesting

Values look like they live "inside" objects because they appear inside in code. They don't. Properties point at values, just like variables do. The universe is full of wires; some start in code, some start from objects.

02

Reading & assigning properties

Reading follows the property wire. Assigning re-aims it — in the same three steps as any assignment.

Read with dot notation, or bracket notation when the name is a string in a variable:

console.log(sherlock.age);          // 64

let propertyName = prompt('What?');
alert(sherlock[propertyName]);     // read by computed name

Property names are case-sensitive and unique per objectage and Age would be two entirely different properties, and an object can't have two properties with the same name.

Assignment, in three steps

Exactly like assigning to a variable:

  1. Figure out which wire is on the left: sherlock.age (follow sherlock, then pick the age wire — we don't care what it currently points at).
  2. Figure out the value on the right: 65.
  3. Point that wire at that value.
sherlock.age = 65; // from now on, sherlock.age reads 65
03

Missing properties & the rules

obj.prop is a question. JavaScript answers it with a fixed procedure — the same one the lab walks.

The rules for obj.prop
  1. Figure out the value of the part before the dot.
  2. If that value is null or undefined, throw immediately.
  3. If the property exists, the result is the value its wire points at.
  4. If it doesn't exist, the result is undefined.

So a missing property gives undefined — not because there's a property pointing at undefined, but because the rules say so:

console.log(sherlock.boat); // undefined

And chaining onto that undefined throws. Two dots means applying the rules twice:

Think first
console.log(sherlock.boat.name); // ?
Answer · TypeError

First resolve sherlock.boat: sherlock is an object with no boat property, so sherlock.boat is undefined. Then evaluate undefined.name — and rule 2 says undefined on the left of a dot throws a TypeError. Step it in the lab to watch it happen.

There's no deeper reason. Computers follow the rules.

04

Recap

  • Properties are wires, like variables — but they start from objects. They point at values; they never contain them.
  • Property names are case-sensitive and unique per object.
  • Assignment is three steps: find the left wire, find the right value, point the wire at it.
  • obj.prop: evaluate the left; if it's null/undefined, throw; if the property exists, return its value; otherwise return undefined.