Skip to main content

Checking whether a property exists in an object

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.

MethodSees inheritedOwn onlySafe for any objectExample
'key' in objyesnoyes'name' in user
obj.hasOwnProperty('key')noyesnot always, the method can be overriddenuser.hasOwnProperty('name')
Object.hasOwn(obj, 'key')noyesyesObject.hasOwn(user, 'name')
obj.key !== undefinednot alwaysnoyesuser.name !== undefined
GoalBest approach
------
Check any property, including inherited ones'prop' in obj
Check an own property onlyObject.hasOwn(obj, 'prop')
Support for old browsersobj.hasOwnProperty('prop')
Check that the value is not undefinedobj.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.

Short Answer

Interview ready
Premium

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