When working with objects in JavaScript, you’ll often need to check if an object contains a specific property. There are two main ways to test for the existence of a property:
- The in operator
- The hasOwnProperty() method
At first glance, these two seem interchangeable. But there are important differences in how inherited properties are handled.
How in Operator Works
The in
operator checks if the specified property exists in the object, or anywhere in its prototype chain.
For example:
const person = {
name: 'John'
};
'name' in person; // true
'toString' in person; // true
The ‘name’ property exists directly on the person object. But ‘toString’ is inherited from person’s prototype chain.
in
returns true for both existing and inherited properties.
How hasOwnProperty() method Works
The hasOwnProperty()
method checks if the property exists on the object instance itself, not including properties from the prototype chain.
Learn more about it here : JavaScript hasOwnProperty() method of an Object
For example:
const person = {
name: 'John'
};
person.hasOwnProperty('name'); // true
person.hasOwnProperty('toString'); // false
‘string'(name) exists only on person, so hasOwnProperty()
returns true. But ‘toString’ is inherited, so it returns false.
The Difference With Inherited Properties
The main difference between using in
and hasOwnProperty()
when dealing with inheritance in JavaScript is:
- The
in
operator will return true for properties that are inherited from an object’s prototype chain. - The
hasOwnProperty()
method will only return true for properties that are defined directly on the object instance itself, not inherited properties.
In JavaScript, objects can inherit properties and methods from their prototype chain. Properties like toString and constructor exist on the Object prototype and are inherited by all objects:
const obj = {};
'constructor' in obj; // true
obj.hasOwnProperty('constructor'); // false
The in
operator returns true for these inherited properties. But they don’t actually exist directly on the obj object.
With in, this can accidentally overwrite the constructor property. hasOwnProperty() avoids this issue by not checking the prototype chain.
The Dangers of in with Inherited Properties
To demonstrate the issue, all objects inherit a constructor property from Object.prototype:
const obj = {};
'constructor' in obj; // true
This seems to imply that obj has its own constructor. But hasOwnProperty()
reveals the truth:
obj.hasOwnProperty('constructor'); // false
The constructor was inherited, not defined on obj itself.
Accidentally overriding inherited properties like this can cause bugs:
function Person(name) {
this.name = name;
}
const me = new Person('John');
// Override inherited constructor
'constructor' in me; // true - uh oh
me.constructor = function() {};
// me's constructor is now broken
Avoiding Issues with hasOwnProperty()
The hasOwnProperty()
method avoids such bugs by distinguishing own vs inherited properties:
const me = new Person('John');
me.hasOwnProperty('constructor'); // false - good
if (!me.hasOwnProperty('constructor')) {
me.constructor = function() {};
}
When to Use in vs hasOwnProperty()
- Use in to check if a property exists before accessing it. But be careful with inherited properties.
- Use hasOwnProperty() to check if a property belongs to the object instance itself. This is better in most cases.
- Use in to check if an object has a method you want to call. Like checking for ‘toString’ before calling it.
Difference between in operator and hasOwnProperty()
Here is a table summarizing the key differences between the in
operator and hasOwnProperty()
method in JavaScript:
in | hasOwnProperty() | |
---|---|---|
Checks prototype chain | Yes | No |
Returns true for inherited properties | Yes | No |
Returns true for own properties | Yes | Yes |
Handles inherited methods | Yes | No |
Safer for checking property existence | No | Yes |
Can cause issues with inherited properties like constructor | Yes | No |
Use case – check before calling a method | Good | Avoid |
Use case – check if property exists on object | Avoid | Good |
Conclusion
The in
operator checks for properties in the entire prototype chain. hasOwnProperty()
only checks the object instance itself.
In most cases, hasOwnProperty()
is the safer choice to avoid issues with inherited properties. But in
is useful when you need to check for a method before calling it.
Understanding these differences will help you write better JavaScript code and avoid bugs!