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 }.
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.
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.
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.
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 object — age and Age would be two entirely different properties, and an object can't have two properties with the same name.
Exactly like assigning to a variable:
- Figure out which wire is on the left:
sherlock.age(followsherlock, then pick theagewire — we don't care what it currently points at). - Figure out the value on the right:
65. - Point that wire at that value.
sherlock.age = 65; // from now on, sherlock.age reads 65
Missing properties & the rules
obj.prop is a question. JavaScript answers it with a fixed procedure — the same one the lab walks.
obj.prop- Figure out the value of the part before the dot.
- If that value is
nullorundefined, throw immediately. - If the property exists, the result is the value its wire points at.
- 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:
console.log(sherlock.boat.name); // ?
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.
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 returnundefined.