Skip to main content

Checking whether a property exists in an object

You check for a property with the in operator, the hasOwnProperty() method, the Object.hasOwn() function, or by comparing the value with undefined. These options are not interchangeable: they treat the prototype differently and they react differently to a property whose value is undefined.

Theory

TL;DR

  • 'key' in obj is the most universal option: it returns true for own properties and for ones inherited from the prototype.
  • obj.hasOwnProperty('key') checks own properties only and ignores the prototype, the classic approach.
  • Object.hasOwn(obj, 'key') is the modern standard from ES2022: the same semantics as hasOwnProperty, but more robust.
  • obj.key !== undefined checks the value rather than the key, so it lies when the value really is undefined.
  • Short rule: need every property, use in; need own properties only, use Object.hasOwn.

Quick example

javascript
const user = { name: 'Maria', age: 25 }; console.log('age' in user); // true console.log('city' in user); // false console.log(user.hasOwnProperty('age')); // true console.log(Object.hasOwn(user, 'city')); // false

The in operator, the most universal way

javascript
const user = { name: 'Maria', age: 25 }; console.log('age' in user); // true console.log('city' in user); // false

The operator checks whether the key exists in the object, including properties inherited from the prototype. The left side is a string or a Symbol, the right side is the object itself.

An example with inheritance:

javascript
const person = { species: 'human' }; const user = Object.create(person); user.name = 'Maria'; console.log('species' in user); // true (inherited)

species is not stored on user directly, but it lives on its prototype person, so in returns true. This is also why 'toString' in {} is true: the method comes from Object.prototype.

hasOwnProperty(), own properties only

javascript
const user = { name: 'Maria', age: 25 }; console.log(user.hasOwnProperty('age')); // true console.log(user.hasOwnProperty('city')); // false

Unlike in, the method ignores the prototype and looks only at properties that are really defined on the object itself.

The difference in practice:

javascript
const person = { species: 'human' }; const user = Object.create(person); user.name = 'Maria'; console.log('species' in user); // true console.log(user.hasOwnProperty('species')); // false

Object.hasOwn(), the modern counterpart of hasOwnProperty

ES2022 added a safer and more readable form:

javascript
const user = { name: 'Maria' }; console.log(Object.hasOwn(user, 'name')); // true console.log(Object.hasOwn(user, 'city')); // false

It works exactly like hasOwnProperty, but it does not depend on what happens inside the object itself. Two cases where hasOwnProperty breaks and Object.hasOwn does not:

javascript
// 1. An object with no prototype simply has no hasOwnProperty method. const dict = Object.create(null); dict.token = 1; // dict.hasOwnProperty('token'); // TypeError console.log(Object.hasOwn(dict, 'token')); // true // 2. An own property with the same name shadows the method. const data = { hasOwnProperty: () => false, id: 7 }; console.log(data.hasOwnProperty('id')); // false, overridden console.log(Object.hasOwn(data, 'id')); // true

Comparing with undefined, the simplest but not always accurate way

javascript
const user = { name: 'Maria' }; if (user.age !== undefined) { console.log('The age property exists'); } else { console.log('There is no age property'); }

The downside: if the property does exist but holds undefined, you get a false negative.

javascript
const user = { age: undefined }; console.log(user.age !== undefined); // false, although the key exists

The shorter if (user.age) check is wrong for the same reason: it discards 0, '', null and false, which are perfectly valid values.

Comparison of the options

OptionWhat it checksSees the prototypeReliability
'key' in objwhether the key existsYesExcellent choice
obj.hasOwnProperty('key')own properties onlyNoClassic
Object.hasOwn(obj, 'key')own properties onlyNoModern standard
obj.key !== undefinedvalue is not undefinedNoCan be misleading

To check whether an object has a property, use 'key' in obj when every property counts, inherited ones included, or Object.hasOwn(obj, 'key') when you need own properties only.

Common mistakes

  • Confusing the key with its value. obj.key !== undefined returns false for a property that exists and holds undefined. Check the key with in or Object.hasOwn.
  • Shortening it to if (obj.key). The values 0, '', null, NaN and false are falsy, so existing properties get silently skipped.
  • Forgetting the prototype. The in operator also sees toString, constructor and other inherited members, so for data that came from outside prefer Object.hasOwn.
  • Calling hasOwnProperty on an Object.create(null) object. Such an object has no prototype, so the method is missing and the call throws a TypeError.
  • Trusting hasOwnProperty on user input. Incoming JSON may carry its own hasOwnProperty key and shadow the method. Object.hasOwn or Object.prototype.hasOwnProperty.call(obj, key) are immune to that.
  • Writing in with a variable name instead of a string. key in obj checks the value of the variable key, while 'key' in obj checks the literal key "key". These are two different checks.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.