How do I check if an object has a specific property in JavaScript?
Consider the following example:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Are there alternative methods to check if an object has a specific property in JavaScript?
To check if an object has a specific property in JavaScript, you can use several methods including the hasOwnProperty() method, the in operator, the newer Object.hasOwn() method, or by comparing property values to undefined. Each approach has different behaviors regarding prototype chain traversal and performance characteristics.
Contents
- Understanding Property Checking Methods
- hasOwnProperty() Method
- in Operator
- Object.hasOwn() - The Modern Alternative
- Alternative Approaches
- Performance Comparison
- Edge Cases and Best Practices
Understanding Property Checking Methods
JavaScript provides multiple ways to check whether an object has a specific property, but they behave differently regarding prototype chain traversal and have various performance implications. The choice of method depends on whether you need to check for own properties only or also inherited properties, as well as performance requirements and browser compatibility concerns.
Let’s explore the primary methods available for property checking in JavaScript:
hasOwnProperty()- Checks only own properties (not inherited from prototype)inoperator - Checks both own and inherited propertiesObject.hasOwn()- Modern alternative tohasOwnProperty()with improved safety- Comparing with
undefined- Quick check but has limitations Object.keys()withincludes()- Less performant but simple
hasOwnProperty() Method
The hasOwnProperty() method is the traditional way to check if an object has a specific property. This method returns true only if the property exists directly on the object itself, not in its prototype chain.
const example = { key: 1 };
console.log(example.hasOwnProperty('key')); // true
console.log(example.hasOwnProperty('toString')); // false (inherited property)
However, hasOwnProperty() has some important limitations:
- Can be overridden: If an object has its own
hasOwnPropertyproperty, it can interfere with the method’s functionality. - Not available on all objects: Objects created with
Object.create(null)don’t inherit fromObject.prototype, so they don’t havehasOwnProperty().
Example of the override problem:
const hedgehog = {
name: "shadow",
color: "black",
hasOwnProperty() { return false; } // Override the method
};
console.log(hedgehog.hasOwnProperty('color')); // false (incorrect!)
To safely use hasOwnProperty() on objects that might override it, you can use:
// Safe way to use hasOwnProperty
Object.prototype.hasOwnProperty.call(obj, 'key');
in Operator
The in operator checks if a specified property exists in an object or its prototype chain. This is different from hasOwnProperty() because it includes inherited properties.
const example = { key: 1 };
console.log('key' in example); // true (own property)
console.log('toString' in example); // true (inherited property)
console.log('nonExistent' in example); // false
The in operator is useful when you want to check for properties regardless of where they’re defined in the prototype chain. However, this can sometimes lead to unexpected results if you’re only interested in properties directly on the object.
Example showing the difference between in and hasOwnProperty():
const example = {};
example.prop = "exists";
// hasOwnProperty only checks own properties
console.log(example.hasOwnProperty('prop')); // true
console.log(example.hasOwnProperty('toString')); // false
// in operator checks both own and inherited properties
console.log('prop' in example); // true
console.log('toString' in example); // true
console.log('hasOwnProperty' in example); // true
Object.hasOwn() - The Modern Alternative
Object.hasOwn() is a newer method introduced in ECMAScript 2022 as a safer alternative to Object.prototype.hasOwnProperty(). It addresses many of the limitations of the traditional method.
According to the MDN documentation, Object.hasOwn() is recommended over hasOwnProperty() in browsers that support it.
const example = {};
example.prop = "exists";
// Object.hasOwn only returns true for direct properties
console.log(Object.hasOwn(example, 'prop')); // true
console.log(Object.hasOwn(example, 'toString')); // false
console.log(Object.hasOwn(example, 'hasOwnProperty')); // false
Key advantages of Object.hasOwn():
- Works with Object.create(null): Unlike
hasOwnProperty(), it works on objects that don’t inherit fromObject.prototype. - Cannot be overridden: It’s a static method, so it can’t be overridden by object properties.
- Cleaner syntax: More concise than
Object.prototype.hasOwnProperty.call()
Example with Object.create(null):
const x = Object.create(null);
x.prop = 'value';
console.log(Object.hasOwn(x, 'prop')); // true
console.log(x.hasOwnProperty('prop')); // TypeError: x.hasOwnProperty is not a function
Alternative Approaches
Comparing with undefined
One quick alternative is to check if the property is not undefined. However, this approach has limitations because a property can legitimately have an undefined value.
const example = { key: undefined };
console.log(example.key !== undefined); // false (but property exists!)
A more reliable version that checks for both existence and non-undefined value:
function hasProperty(obj, prop) {
return obj[prop] !== undefined;
}
// But this still fails if the property exists with undefined value
Object.keys() with includes()
You can get all own properties and check if the property name is in the array:
const example = { key: 1 };
console.log(Object.keys(example).includes('key')); // true
console.log(Object.keys(example).includes('toString')); // false
This approach is less performant for single property checks because it creates an array of all keys, but it’s useful when you need to check multiple properties.
Reflect.has()
The Reflect.has() method is similar to the in operator but provides a function interface:
const example = { key: 1 };
console.log(Reflect.has(example, 'key')); // true
console.log(Reflect.has(example, 'toString')); // true
Performance Comparison
Performance varies significantly between methods, and the differences become important when checking properties frequently or in performance-critical code.
According to performance benchmarks, here’s the general performance ranking:
- Direct property access (
obj[key] !== undefined) - Fastest inoperator - Moderate performancehasOwnProperty()- Slower than direct accessObject.hasOwn()- Similar tohasOwnProperty()or slightly slowerObject.keys().includes()- Slowest for single checks
Important performance considerations:
-
Object.keys() approach: Creating an array of all keys is expensive for large objects. As one Stack Overflow answer notes, checking for truthy values using
[]is much faster than usinginorhasOwnProperty. -
Prototype chain traversal: The
inoperator traverses the prototype chain, which can be slower for deeply nested inheritance chains. -
Method lookup: Calling
hasOwnProperty()on an object means looking up the method first, resolving where it came from, and then binding it to the object. As this analysis explains,Object.hasOwn()avoids this extra lookup step.
Edge Cases and Best Practices
Objects with Overridden hasOwnProperty()
When working with objects that might have overridden the hasOwnProperty() method, always prefer Object.hasOwn() or the safe Object.prototype.hasOwnProperty.call() approach:
// Safe approaches that work even when hasOwnProperty is overridden
Object.hasOwn(obj, 'key'); // Best if supported
Object.prototype.hasOwnProperty.call(obj, 'key'); // Fallback for older browsers
Objects Created with Object.create(null)
Objects created with Object.create(null) don’t inherit from Object.prototype, so they lack hasOwnProperty() entirely:
const x = Object.create(null);
x.prop = 'value';
// These work:
console.log('prop' in x); // true
console.log(Object.hasOwn(x, 'prop')); // true
// This fails:
console.log(x.hasOwnProperty('prop')); // TypeError: x.hasOwnProperty is not a function
Properties with Undefined Values
Be careful when checking properties that might legitimately have undefined values. The strict equality check approach fails in this case:
const obj = { key: undefined };
// These correctly identify the property exists:
console.log('key' in obj); // true
console.log(Object.hasOwn(obj, 'key')); // true
console.log(obj.hasOwnProperty('key')); // true
// This incorrectly suggests the property doesn't exist:
console.log(obj.key !== undefined); // false
Browser Compatibility
While Object.hasOwn() is the modern recommended approach, consider browser compatibility:
Object.hasOwn(): Supported in modern browsers (Chrome 93+, Firefox 92+, Safari 15.4+, Edge 93+)hasOwnProperty(): Universal supportinoperator: Universal support
For maximum compatibility, you can use a polyfill or feature detection:
function safeHasOwn(obj, prop) {
return typeof Object.hasOwn === 'function'
? Object.hasOwn(obj, prop)
: Object.prototype.hasOwnProperty.call(obj, prop);
}
Summary of Recommendations
- Modern code: Use
Object.hasOwn()for checking own properties - Legacy browsers: Use
Object.prototype.hasOwnProperty.call()as fallback - Prototype checking: Use
inoperator when inherited properties should be included - Performance-critical code: Consider direct property access (
obj[key] !== undefined) but be aware of limitations - Multiple property checks: Use
Object.keys()when checking several properties
Here’s a quick reference table:
| Method | Checks Own Properties Only | Prototype Chain | Performance | Safety |
|---|---|---|---|---|
Object.hasOwn() |
✓ | ✗ | Good | ✓ |
hasOwnProperty() |
✓ | ✗ | Moderate | ✗ |
in operator |
✗ | ✓ | Moderate | ✓ |
obj[key] !== undefined |
✓ | ✗ | Best | ✗ |
Object.keys().includes() |
✓ | ✗ | Poor | ✓ |
Sources
- Object.prototype.hasOwnProperty() - JavaScript | MDN
- Object.hasOwn() - JavaScript | MDN
- 3 Ways to Check If an Object Has a Property/Key in JavaScript
- The Uses of ‘in’ vs ‘hasOwnProperty’ - A Drip of JavaScript
- The Difference Between in and hasOwnProperty in JavaScript - Mastering JS
- How to Check If an Object Has a Property in JavaScript | Built In
- Speed test: === vs in vs hasOwnProperty
- Object.hasOwn() versus Object.prototype.hasOwnProperty() - Kieran Barker
- Which is faster: obj.hasOwnProperty(prop) vs Object.keys(obj).includes(prop) - DEV Community
- What is the hasOwnProperty() method in JavaScript?
Conclusion
Checking if an object has a specific property in JavaScript requires understanding the different available methods and their behaviors. The key takeaways are:
- Use
Object.hasOwn()for modern JavaScript when you need to check only own properties - it’s the safest and most reliable method - Use the
inoperator when you want to include inherited properties in your check - Avoid direct property comparison with
undefinedwhen the property might legitimately haveundefinedas its value - Consider performance implications - direct property access is fastest but has limitations, while
Object.keys().includes()is slowest but most reliable for complex cases - Handle edge cases like objects with overridden
hasOwnProperty()methods or objects created withObject.create(null)
The best method depends on your specific use case, but Object.hasOwn() is generally the recommended approach for modern JavaScript development when checking own properties only. For maximum compatibility, use feature detection or Object.prototype.hasOwnProperty.call() as a fallback.