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
| Parameter | Type | Default | Description |
|---|---|---|---|
| obj | object | — | The object to check |
| prop | string | symbol | — | The 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)vsobj.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
| Parameter | Type | Description |
|---|---|---|
obj | object | The object to inspect. Throws TypeError if null or undefined. |
prop | string | symbol | The 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
- Object.keys() — Get object keys
- Object.entries() — Get object entries