The key difference is that in will return true for inherited properties, whereas hasOwnProperty() will return false for inherited properties.
There are mainly two methods to check the existence of a key in JavaScript Object. The first one is using “in operator” and the second one is using “hasOwnProperty() method”. Method 1: Using 'in' operator: The in operator returns a boolean value if the specified property is in the object.
hasOwnProperty() The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
The short answer is "no". All JavaScript object keys are strings. Even if you pass an object as a key, the object's toString() will be called on it, and the key will be stringified to [object Object] .
Be careful - they won't produce the same result.
in
will also return true
if key
gets found somewhere in the prototype chain, whereas Object.hasOwnProperty
(like the name already tells us), will only return true
if key
is available on that object directly (its "owns" the property).
I'l try to explain with another example. Say we have the following object with two properties:
function TestObj(){
this.name = 'Dragon';
}
TestObj.prototype.gender = 'male';
Let's create instance of TestObj:
var o = new TestObj();
Let's examine the object instance:
console.log(o.hasOwnProperty('name')); // true
console.log('name' in o); // true
console.log(o.hasOwnProperty('gender')); // false
console.log('gender' in o); // true
Conclusion:
in operator returns true always, if property is accessible by the object, directly or from the prototype
hasOwnProperty() returns true only if property exists on the instance, but not on its prototype
If we want to check that some property exist on the prototype, logically, we would say:
console.log(('name' in o) && !o.hasOwnProperty('name')); //false
console.log(('gender' in o) && !o.hasOwnProperty('gender')); //true - it's in prototype
Finally:
So, regarding to statement that these two conditions ...
if (key in object)
if (object.hasOwnProperty(key))
...produce the same result, the answer is obvious, it depends.
in
will also check for inherited properties, which is not the case for hasOwnProperty
.
In summary, hasOwnProperty()
does not look in the prototype while in
does look in the prototype.
Taken from O'Reilly High Performance Javascript:
You can determine whether an object has an instance member with a given name by using the hasOwnProperty() method and passing in the name of the member. To determine whether an object has access to a property with a given name, you can use the in operator. For example:
var book = {
title: "High Performance JavaScript",
publisher: "Yahoo! Press"
};
alert(book.hasOwnProperty("title")); //true
alert(book.hasOwnProperty("toString")); //false
alert("title" in book); //true
alert("toString" in book); //true
In this code, hasOwnProperty() returns true when “title” is passed in because title is an object instance; the method returns false when “toString” is passed in because it doesn’t exist on the instance. When each property name is used with the in operator, the result is true both times because it searches the instance and prototype.
You got some really great answers. I just want to offer something that will save you the need for checking "hasOwnProperty" while iterating an object.
When creating an object usually people will create it in this way:
const someMap = {}
// equivalent to: Object.create(Object.prototype)
// someMap.constructor will yield -> function Object() { [native code] }
Now, if you want to iterate through "someMap" you will have to do it this way:
const key
for(key in someMap ){
if (someMap.hasOwnProperty(key)) {
// Do something
}
}
We are doing so in order to avoid iterating over inherited properties.
If you intend to create a simple object that will only be used as a "map" (i.e. key - value pairs) you can do so like that:
const newMap = Object.create(null);
// Now, newMap won't have prototype at all.
// newMap.constructor will yield -> undefined
So now it will be safe to iterate like this:
for(key in cleanMap){
console.log(key + " -> " + newMap [key]);
// No need to add extra checks, as the object will always be clean
}
I learned this awesome tip here
The other form (called for in) enumerates the property names (or keys) of an object. On each iteration, another property name string from the object is assigned to the variable. It is usually necessary to test object.hasOwnProperty(variable) to determine whether the property name is truly a member of the object or was found instead on the prototype chain.
for (myvar in obj) {
if (obj.hasOwnProperty(myvar)) { ... } }
(from Crockford's Javascript: The Good Parts)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With