hasOwnProperty()
ES3+Returns true when the object itself defines the named property, ignoring anything inherited from the prototype chain. Inherited from Object.prototype, it is the classic way to distinguish an object's own data from prototype members — with Object.hasOwn() as its safer modern successor.
Syntax
obj.hasOwnProperty(prop)Parameters
prop string The property name to check
Return Value
true if the object has the property, otherwise false
Examples
const obj = { name: 'John' };
console.log(obj.hasOwnProperty('name'));
console.log(obj.hasOwnProperty('age'));
console.log(obj.hasOwnProperty('toString')); 📌 When to Use
Use hasOwnProperty() — or, in ES2022+ code, Object.hasOwn() — whenever the distinction between "defined on this object" and "reachable through inheritance" matters. The canonical case is filtering for...in loops, which enumerate inherited enumerable properties too; an own-property guard keeps prototype additions from leaking into your data processing. It is also the right tool for distinguishing a property that exists with the value undefined from one that does not exist at all — obj.key === undefined cannot tell those apart, but an own-property check can, which matters for optional-field semantics in APIs and for cache entries whose legitimate value is undefined. Other everyday uses: checking whether a plain-object dictionary already contains a key before inserting, validating that a payload actually carries a required field rather than inheriting something with the same name, and writing serializers or polyfills that must process own state only. Prefer the in operator when inherited members should count (for example feature-detecting methods), and prefer Map when collection semantics get heavy — Map.has() carries none of the prototype-related pitfalls this method drags along.
⚠️ Common Mistakes
Trusting user-controlled JSON keys - a payload like {"hasOwnProperty": 1} shadows the method, so data.hasOwnProperty("x") throws "not a function" at runtime. Any object whose keys come from the outside world must be checked with Object.hasOwn(data, "x") or the Object.prototype.hasOwnProperty.call() pattern instead.
Using hasOwnProperty to test for "has a usable value" - it returns true for own properties whose value is undefined or null, so ({ a: undefined }).hasOwnProperty("a") is true. Pair the existence check with an explicit value check when both presence and usability matter.
Calling hasOwnProperty directly on objects that might have it overridden - use Object.prototype.hasOwnProperty.call(obj, prop) for safety.
Using hasOwnProperty on objects created with Object.create(null) - they do not have this method, use Object.hasOwn() or the call pattern.
Confusing hasOwnProperty with the "in" operator - "in" checks the entire prototype chain, hasOwnProperty only checks own properties.
✅ Best Practices
Standardize on Object.hasOwn(obj, key) in codebases targeting ES2022+ - it works on null-prototype objects, cannot be shadowed by object data, and reads as a static utility rather than a method the object must safely inherit; keep the .call() pattern only for legacy targets.
Prefer Object.keys() or Object.entries() iteration over for...in plus a hasOwnProperty guard in new code - the keys array already contains only own enumerable properties, eliminating the guard entirely and making the iteration rules explicit to readers.
Use Object.hasOwn(obj, prop) in modern JavaScript (ES2022+) - it is safer and more concise than hasOwnProperty.
In for...in loops, always check hasOwnProperty to filter out inherited properties: if (obj.hasOwnProperty(key)) { ... }
For untrusted objects, use the safe pattern: Object.prototype.hasOwnProperty.call(obj, prop) or the shorthand ({}).hasOwnProperty.call(obj, prop)
⚡ Performance Notes
hasOwnProperty() is effectively O(1): it consults the object's own property table without walking the prototype chain. Object.hasOwn() performs identically and is implemented as a direct intrinsic in modern engines. Performance pitfalls here are about access patterns, not the check itself: probing objects whose shapes vary wildly makes the call site megamorphic and slower, whereas checking keys on objects that share one hidden class stays on the inline-cached fast path. The Object.prototype.hasOwnProperty.call(obj, key) pattern adds a negligible function-call cost — correctness, not speed, decides between the patterns. If your code performs millions of membership tests on a mutating keyed collection, Map.has() is the structure designed for that job; it typically beats plain-object probing while also sidestepping every shadowing and null-prototype hazard described above.
🌍 Real World Example
Safe Object Property Iteration
This walkthrough lines up the three ways to test property ownership — a direct method call, the defensive Object.prototype.hasOwnProperty.call() pattern, and modern Object.hasOwn() — against an object that inherits data from a custom prototype. getOwnProperties() shows the classic for...in guard extracting only own keys. The finale is the trap that motivates the safe patterns: an object whose own hasOwnProperty key shadows the real method answers falsely, while Object.hasOwn() keeps telling the truth. This exact scenario occurs in practice with user-supplied JSON payloads.
// Base object with inherited method
const proto = { inherited: 'from prototype' };
const obj = Object.create(proto);
obj.own1 = 'value1';
obj.own2 = 'value2';
// Method 1: Direct hasOwnProperty (may be overridden)
console.log(obj.hasOwnProperty('own1')); // true
console.log(obj.hasOwnProperty('inherited')); // false
// Method 2: Safe pattern (recommended for untrusted objects)
const hasOwn = Object.prototype.hasOwnProperty;
console.log(hasOwn.call(obj, 'own1')); // true
// Method 3: Modern Object.hasOwn (ES2022+)
console.log(Object.hasOwn(obj, 'own1')); // true
console.log(Object.hasOwn(obj, 'inherited')); // false
// Safe for...in iteration
function getOwnProperties(obj) {
const result = {};
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
result[key] = obj[key];
}
}
return result;
}
console.log(getOwnProperties(obj));
// { own1: 'value1', own2: 'value2' }
// Handle edge case: object with overridden hasOwnProperty
const tricky = { hasOwnProperty: () => false, name: 'test' };
console.log(tricky.hasOwnProperty('name')); // false (wrong!)
console.log(Object.hasOwn(tricky, 'name')); // true (correct!)