Suggest an editImprove this articleRefine the answer for “Accessing a non-existent object property”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Accessing a property that does not exist does not throw: the expression simply evaluates to `undefined`.** A `TypeError` appears only when you go further down the chain and try to read a property of that `undefined`. Optional chaining `?.` makes the access safe, and `??` adds a default value. ```javascript const user = { name: 'Maria' }; console.log(user.age); // undefined, no error console.log(user.address?.city); // undefined, also no error console.log(user.address.city); // TypeError ``` **Key point:** one level gives `undefined`, two levels over a missing value gives a `TypeError`, so use `?.` for nested data.Shown above the full answer for quick recall.Answer (EN)Image**If you access a property that does not exist on an object, nothing is thrown and the result is `undefined`.** An error appears only when that `undefined` is then treated as an object and one of its own properties is read. ## Theory ### TL;DR - `obj.missing` returns `undefined`, it does not throw. - Dynamic access `obj[key]` behaves exactly the same way. - A `TypeError` shows up at the next step of the chain: `undefined.city`. - Safe options: a manual `&&` check, optional chaining `?.`, and a default value via `??`. - To tell "the property is absent" from "the property is `undefined`" you need `in` or `hasOwnProperty`. ### Quick example ```javascript const user = { name: 'Maria' }; console.log(user.name); // "Maria" console.log(user.age); // undefined console.log(user.address); // undefined ``` JavaScript does not raise an error, it simply returns `undefined`. ### Why `undefined` is returned When reading a property, the engine does the following: 1. Checks whether the property exists **on the object itself**. 2. If it **does**, returns its value. 3. If it **does not**, keeps looking up the prototype chain. 4. If it is nowhere to be found, returns `undefined`. ```javascript user.hasOwnProperty('age'); // false user.age; // undefined ``` This is a deliberate language decision: a missing property is not an error condition but an ordinary state of the data. ### When an error does occur The error appears when you go **further** down the chain: ```javascript console.log(user.address.city); // TypeError ``` The reason: `user.address` is `undefined`, and **properties cannot be requested from `undefined`**. In a browser the message looks roughly like `TypeError: Cannot read properties of undefined (reading 'city')`. The same applies to `null`: neither value has an object wrapper, so any property read on them fails. ### How to read nested properties safely **Option 1. Manual checks.** ```javascript if (user.address && user.address.city) { console.log(user.address.city); } ``` **Option 2. Optional chaining `?.` (the modern approach).** ```javascript console.log(user.address?.city); // undefined, but with no error ``` If the value to the left of `?.` is `null` or `undefined`, JavaScript **stops evaluating** the whole chain and returns `undefined`. **Option 3. A default value via `??`.** ```javascript console.log(user.address?.city ?? 'Not specified'); // "Not specified" ``` ### Dynamic access and existence checks With square brackets the behaviour is identical: ```javascript const key = 'email'; console.log(user[key]); // undefined, when the property is absent ``` The catch is that `undefined` also comes back when the property does exist but its value is `undefined`. Telling those two cases apart requires separate checks: ```javascript const account = { email: undefined }; account.email; // undefined 'email' in account; // true, the property exists account.hasOwnProperty('email'); // true, and it is an own property Object.hasOwn(account, 'email'); // true, the modern form ``` `in` also counts properties inherited from the prototype, while `hasOwnProperty` and `Object.hasOwn` count only own ones. ### Summary tables | Situation | Result | Explanation | | --- | --- | --- | | `user.age` | `undefined` | the property is absent | | `user.age.city` | `TypeError` | `undefined` is not an object | | `'age' in user` | `false` | an existence check | | `user.hasOwnProperty('age')` | `false` | a check for own properties only | | `user.name ?? 'none'` | `'Maria'` | the value is returned | | `user.age ?? 'none'` | `'none'` | the default value is substituted | | Behaviour | What happens | | --- | --- | | `obj.missing` | returns `undefined` | | No error | even when the property does not exist | | An error appears | when trying to go deeper (`undefined.city`) | | The fix | use `?.` or `??` | An example to tie it together: ```javascript const user = { name: 'Maria' }; console.log(user.age); // undefined console.log(user.age?.value); // undefined (no error) console.log(user.age ?? 'none'); // "none" console.log(user.age.value); // TypeError ``` ### Common mistakes - **Expecting an error where there is none.** A typo in a property name quietly yields `undefined`, and the bug surfaces much later, somewhere else in the code. - **Reading a deep chain without `?.`.** API data often arrives incomplete, and `data.user.profile.avatar` breaks at the first missing level. - **Putting `?.` only at the end of the chain.** `user.address?.city` does not help when `user` itself may be `undefined`. That needs `user?.address?.city`. - **Confusing "no such property" with "the value is `undefined`".** The comparison `obj.key === undefined` cannot distinguish the two, which is what `in` and `Object.hasOwn` are for. - **Calling a method that does not exist.** `obj.doSomething()` throws `TypeError: obj.doSomething is not a function`, because `undefined` cannot be called. The safe form is `obj.doSomething?.()`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.