jsguides

Object.hasOwn()

Object.hasOwn(obj, prop)

Object.hasOwn() is a static method that returns true if the specified object has the indicated property as its own property. If the property is inherited or does not exist, it returns false.

Syntax

Object.hasOwn(obj, prop)

Parameters

ParameterTypeDefaultDescription
objobjectThe object to check
propstring | symbolThe property name or Symbol to check

Examples

Basic usage

const obj = { name: 'Alice', age: 30 };

console.log(Object.hasOwn(obj, 'name'));
// true

console.log(Object.hasOwn(obj, 'age'));
// true

console.log(Object.hasOwn(obj, 'gender'));
// false

The basic case covers objects you define yourself, but the real test is the prototype chain. Object.hasOwn() draws a clear line between properties set directly on an object and those inherited through [[Prototype]], which matters when you are iterating over objects built with Object.create() or working with class instances that inherit from a parent.

Inherited properties return false

const parent = { a: 1 };
const child = Object.create(parent);
child.b = 2;

console.log(Object.hasOwn(child, 'a'));
// false — inherited from parent

console.log(Object.hasOwn(child, 'b'));
// true — own property

The prototype check handles string property names, but JavaScript properties can also be Symbols — unique, non-string identifiers often used for metadata or internal bookkeeping. Object.hasOwn() accepts Symbol keys directly, so you can check for those properties without converting them to strings first.

Checking Symbol properties

const sym = Symbol('id');
const obj = { [sym]: 123 };

console.log(Object.hasOwn(obj, sym));
// true

Common Patterns

Once you understand the basic API, Object.hasOwn() slots into everyday guard patterns. The two most common uses are filtering for...in loops and writing safe property deletion helpers. Both rely on the same guarantee: the method tells you whether the property lives directly on the object, regardless of what the prototype chain might contribute.

Filtering own properties in loops

const parent = { inherited: 1 };
const child = Object.create(parent);
child.own = 2;
child.another = 3;

for (const key in child) {
  if (Object.hasOwn(child, key)) {
    console.log(key); // logs: 'own', 'another'
  }
}

Filtering during iteration is the defensive pattern, but sometimes you want to act on a single property. Deleting a property that does not exist is harmless in JavaScript (the delete operator returns true either way), but checking first lets you return a meaningful result or log a warning. Wrapping the check in a helper like the one below keeps the calling code clean.

Safe property checking before deletion

function safeDelete(obj, prop) {
  if (Object.hasOwn(obj, prop)) {
    delete obj[prop];
    return true;
  }
  return false;
}

Object.hasOwn() vs ObjecthasOwnProperty()

Object.hasOwn() is essentially a replacement for ObjecthasOwnProperty(). Key differences:

  • Syntax: Object.hasOwn(obj, prop) vs obj.hasOwnProperty(prop)
  • Null safety: Object.hasOwn() throws TypeError if obj is null/undefined (unlike hasOwnProperty which would silently fail)
  • Modern: Object.hasOwn() is the recommended approach for new code
const obj = { a: 1 };

// Both work for normal objects
obj.hasOwnProperty('a');       // true
Object.hasOwn(obj, 'a');       // true

// But with null/undefined:
Object.hasOwn(null, 'a');     // TypeError
Object.hasOwn(undefined, 'a'); // TypeError

Parameters

ParameterTypeDescription
objobjectThe object to inspect. Throws TypeError if null or undefined.
propstring | symbolThe property name to look up. Non-string, non-symbol values are converted to strings.

What “own property” means

A property is “own” if it was directly set on the object — either in an object literal, via assignment, or with Object.defineProperty(). Inherited properties, which come from the prototype chain, are not own properties. Object.hasOwn() checks only the object itself, not its prototype chain, which is almost always the right check when verifying whether a specific object was given a particular value.

Why it matters in real code

Object.hasOwn() is most valuable in code that loops over user data or merges objects from several sources. In those cases, inherited properties can be misleading, especially when you are using for...in or dealing with objects that do not inherit from Object.prototype. The static form also avoids the need to reach into the target object to call a method on it, which means the check works even when the object has a custom prototype or no prototype at all.

Common failure modes

The biggest mistake is assuming that obj.hasOwnProperty(prop) is always available. That breaks on objects created with Object.create(null) and can be shadowed by a same-named property. Another mistake is using in when you only care about direct properties, which will return true for inherited values too. Object.hasOwn() keeps the intent clear: you are asking whether the object itself owns the property, not whether the name exists anywhere on the prototype chain.

Why Object.hasOwn() over hasOwnProperty()

The older obj.hasOwnProperty(prop) approach has two problems. First, objects created with Object.create(null) have no prototype and therefore no hasOwnProperty method — calling it throws a TypeError. Second, any code could shadow hasOwnProperty by adding its own property with that name. Object.hasOwn() avoids both issues because it is a static method called on the Object constructor rather than on the object itself.

const nullObj = Object.create(null);
nullObj.key = 'value';

// Throws: nullObj.hasOwnProperty is not a function
// nullObj.hasOwnProperty('key');

// Works correctly:
Object.hasOwn(nullObj, 'key'); // true

Browser support

Object.hasOwn() was introduced in ES2022 and is supported in Chrome 93+, Firefox 92+, Safari 15.4+, and Node.js 16.9+. For older environments, use Object.prototype.hasOwnProperty.call(obj, prop) as a safe polyfill.

See Also