Suggest an editImprove this articleRefine the answer for “Checking whether a property exists in an object”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**There are four main ways: the `in` operator (sees both own and inherited properties), `Object.hasOwn()` (the modern, safe check for own properties only), `obj.hasOwnProperty()` (the same, but it can be overridden) and the comparison `obj.key !== undefined` (fastest, but it lies when the value really is `undefined`).** In modern code you use `in` when the whole prototype chain matters, and `Object.hasOwn()` when only own fields do. ```javascript const user = { name: 'Alice', email: undefined }; console.log('email' in user); // true console.log(Object.hasOwn(user, 'email')); // true console.log(user.email !== undefined); // false, misleading ``` **Key point:** `in` checks that a property exists, while `!== undefined` checks its value, and those are different questions.Shown above the full answer for quick recall.Answer (EN)Image**JavaScript gives you several ways to check whether an object has a given property, and each one behaves slightly differently.** The difference is whether the prototype chain is taken into account and whether a value of `undefined` can fool the check. ## Theory ### TL;DR - `'key' in obj` checks that the property exists, including properties inherited from the prototype. - `obj.hasOwnProperty('key')` sees own properties only, but the method can be overridden. - `Object.hasOwn(obj, 'key')` (ES2022) is the modern, safe replacement for `hasOwnProperty()`. - `obj.key !== undefined` checks the value, not the existence, so it is wrong for properties whose value is `undefined`. - `Reflect.has(obj, 'key')` behaves exactly like `in` and is convenient in metaprogramming code. ### Quick example ```javascript const user = { name: 'Alice', age: 25 }; console.log('name' in user); // true console.log(Object.hasOwn(user, 'name')); // true console.log('email' in user); // false ``` ### The in operator The most direct and reliable way to check that a property exists at all. ```javascript const user = { name: 'Alice', age: 25 }; console.log('name' in user); // true console.log('email' in user); // false ``` The operator takes the whole prototype chain into account: ```javascript const person = { isHuman: true }; const user = Object.create(person); user.name = 'Alice'; console.log('name' in user); // true, own property console.log('isHuman' in user); // true, inherited ``` ### The hasOwnProperty() method It checks own properties only, that is, the ones that really belong to the object itself and not to its prototype. ```javascript const person = { isHuman: true }; const user = Object.create(person); user.name = 'Alice'; console.log(user.hasOwnProperty('name')); // true console.log(user.hasOwnProperty('isHuman')); // false ``` Use it when you need to be sure a property is defined on the object itself rather than inherited. > Careful: if someone has overridden `hasOwnProperty`, or the object was created with `Object.create(null)` and therefore has no prototype, call the method like this: ```javascript Object.prototype.hasOwnProperty.call(user, 'name'); ``` ### The Object.hasOwn() method The modern version of `hasOwnProperty` from ES2022, safer because it does not depend on the object's own prototype chain. ```javascript const user = { name: 'Alice' }; console.log(Object.hasOwn(user, 'name')); // true console.log(Object.hasOwn(user, 'email')); // false ``` In new code `Object.hasOwn()` is the recommended choice over `hasOwnProperty()`. ### Checking against undefined A simple but not always safe approach: ```javascript const user = { name: 'Alice' }; console.log(user.name !== undefined); // true console.log(user.email !== undefined); // false ``` The problem is that a property may exist and still hold the value `undefined`: ```javascript const user = { name: undefined }; console.log('name' in user); // true, the property is there console.log(user.name !== undefined); // false, the check misleads you ``` ### Reflect.has() and a comparison of the approaches One more option, from the Reflect API: ```javascript const user = { name: 'Alice' }; console.log(Reflect.has(user, 'name')); // true console.log(Reflect.has(user, 'email')); // false ``` It works exactly like `in`, but is convenient in reflective, metaprogramming code, for example inside a `Proxy` `has` trap. | Method | Sees inherited | Own only | Safe for any object | Example | | --- | --- | --- | --- | --- | | `'key' in obj` | yes | no | yes | `'name' in user` | | `obj.hasOwnProperty('key')` | no | yes | not always, the method can be overridden | `user.hasOwnProperty('name')` | | `Object.hasOwn(obj, 'key')` | no | yes | yes | `Object.hasOwn(user, 'name')` | | `obj.key !== undefined` | not always | no | yes | `user.name !== undefined` | | Goal | Best approach | | --- | --- | | Check any property, including inherited ones | `'prop' in obj` | | Check an own property only | `Object.hasOwn(obj, 'prop')` | | Support for old browsers | `obj.hasOwnProperty('prop')` | | Check that the value is not `undefined` | `obj.key !== undefined`, with care | ### Common mistakes - **Checking existence with `!== undefined`.** A property whose value is `undefined` does exist, yet this check returns `false`. - **Using `if (obj.count)` as an existence check.** `0`, `''`, `false` and `null` are falsy too, so a present field looks missing. - **Calling `hasOwnProperty` directly on an object from `Object.create(null)`.** There is no prototype, so the method is unavailable and you get a `TypeError`; use `Object.hasOwn()`. - **Confusing `in` with iteration.** For arrays `in` checks the index, not the value: `1 in [10, 20]` is `true`, while `20 in [10, 20]` is `false`. - **Forgetting inherited fields.** `'toString' in {}` is `true`, because the method comes from `Object.prototype`. - **Thinking `?.` replaces the check.** `user?.email` only guards against an error on `null`; it does not distinguish a missing field from a field holding `undefined`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.