Object.hasOwn()

Reports whether an object has the given property as its own, ignoring the prototype chain.

Signature
Object.hasOwn(obj, prop)
  • Added in JavaScript ES2022

Parameters

ParameterTypeDescription
$objObjectThe JavaScript object instance to test.
$propstring | symbolThe name or symbol of the property to test.

Return value

booleantrue if the specified object has the specified property as its own property, otherwise false.

Errors

Throws a TypeError if obj is null or undefined.

Object.hasOwn() is the modern, unbreakable replacement for Object.prototype.hasOwnProperty(). It answers the same question — does this object own this key? — but as a static function, so it cannot be sabotaged by the object it is inspecting.

Why it exists

obj.hasOwnProperty(k) is a method lookup on obj, which means it fails in two real situations: when the object was built with Object.create(null) and has no inherited methods at all (a TypeError), and when the object carries its own hasOwnProperty key — easy to hit with parsed JSON or user-supplied form data. Object.hasOwn() is immune to both, which is why linters now flag the method form.

Choosing between hasOwn and in

The in operator searches the whole prototype chain, so 'toString' in {} is true. Object.hasOwn() stops at own properties. Use in when inherited behaviour counts, hasOwn() when you are treating the object as a data record.

What trips people up

Presence is not truthiness. Object.hasOwn(obj, 'k') is true even when the value is undefined, null, 0 or '' — which is exactly the case if (obj.k) gets wrong.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Validate that a parsed JSON payload actually contains a required field
  • Iterate a dictionary safely when keys come from user input
  • Distinguish a missing option from one explicitly set to undefined

Frequently asked questions

What is the difference between Object.hasOwn and the in operator?

Object.hasOwn() checks only the object's own properties, while in also searches the prototype chain, so 'toString' in {} is true but Object.hasOwn({}, 'toString') is false.

Why use Object.hasOwn instead of obj.hasOwnProperty?

Because obj.hasOwnProperty() breaks on null-prototype objects and on any object that has its own key named hasOwnProperty, while the static Object.hasOwn() works in both cases.

Does Object.hasOwn work with symbol keys?

Yes, the second argument may be a string or a symbol.

More examples

Surviving a hostile key

The payload shadows hasOwnProperty with the boolean false, so calling it as a method throws because false is not callable. Object.hasOwn() never touches the object's own keys, so it reports the truth about both amount and the shadowing key itself.

Example · javascript
const parsed = JSON.parse('{"hasOwnProperty": false, "amount": 42}');

try {
  console.log(parsed.hasOwnProperty("amount"));
} catch (err) {
  console.log("threw:", err.constructor.name);   // threw: TypeError
}

console.log(Object.hasOwn(parsed, "amount"));                  // true
console.log(Object.prototype.hasOwnProperty.call(parsed, "amount")); // true
console.log(Object.hasOwn(parsed, "hasOwnProperty"));          // true

Filtering an object by own keys

for...in walks inherited enumerable keys, so it visits both theme and lang. The hasOwn() guard keeps only what the object itself defines, matching what Object.keys() would have given directly.

Example · javascript
const defaults = { theme: "dark", lang: "en" };
const user = Object.create(defaults);
user.lang = "fr";

const ownOnly = {};
for (const key in user) {
  if (Object.hasOwn(user, key)) ownOnly[key] = user[key];
}

console.log(user.theme);        // "dark" — inherited
console.log(ownOnly);           // { lang: 'fr' }
console.log(Object.keys(user)); // [ 'lang' ]

Discussion

  • Be the first to comment on this lesson.