JavaScript hasOwnProperty vs typeof
I searched a lot on Google but couldn't find where I was looking:
Benefits of using Object.hasOwnProperty versus testing if property is undefined
How to tell if a JavaScript native object has a Property / Method?
.. and many other sites, but this is not the place I'm looking for. My real question is:
Why hasOwnProperty
can't it find a method in its superclass (prototype)? And why would anyone even use it hasOwnProperty
? It's a lot slower than typeof
that, and it doesn't work if you're working with inheritance.
.. second question:
In this question, Barney answers what you should use if ('property' in objectVar)
to check if a property exists, but does not explain why. Does anyone know why you would use this structure?
var objA = function(){};
objA.prototype.alertMessage = function(){
return 'Hello A';
};
var objB = function(){
this.hello = function(){
return 'hello';
};
};
// Inheritance
objB.prototype = Object.create(objA.prototype);
objB.prototype.constructor = objA;
var test = new objB();
if (test.hasOwnProperty("alertMessage")){
console.log("hasOwnProperty: " + test.alertMessage());
}
if (typeof test.alertMessage === "function"){
console.log("typeof: " + test.alertMessage());
}
if (test.hasOwnProperty("hello")){
console.log("hasOwnProperty: " + test.hello());
}
if (typeof test.hello === "function"){
console.log("typeof: " + test.hello());
}
source to share
There are a number of reasons one uses (and in some cases should use) hasOwnProperty
, and why its behavior is:
- As the name implies,
hasOwnProperty
checks whether the subject on which you are testing , the property with the given name. If it inherited a method / property from another object (its prototype), then the owner of this property is not an object, but its prototype. Hence the object does not have a property of its own called X -
typeof
It will work most of the time, but the object might look as follows:var o = {foo: undefined}
. Usingtypeof
ono.foo
will give of course"undefined"
, but the object has a property calledfoo
- Usage
if ('properyname' in object)
is a workaround that combines the best of both worlds: in caseo = {foo: undefined};
it will evaluate to true, without the overhead of finding a methodhasOwnPropery
(which is a propertyObject.prototype
) or calling a function with context bindings and all. It will also find properties on the prototype chain.
So, consider the following examples:
var o = {foo: undefined,
toString: undefined};//overwrite inherited method
console.log(typeof o.foo);//undefined
console.log(typeof o.toString);//undefined
console.log(o.hasOwnProperty('toString'));//true
delete(o.toString);
console.log(typeof o.toString);//function
if ('valueOf' in o)
console.log(o.valueOf === Object.prototype.valueOf);//true
if ('foo' in o)
console.log(o.foo);//undefined
Another important note is that your statement about hasOwnProperty
which does not work when dealing with inheritance is simply not true. Every object you use in JS inherits from at least one prototype. It is important to understand, understand and respect this. If you are looping an object, it is a good idea to make sure that you are actually iterating over the properties that belong to the object itself. Hence, it is not uncommon to see:
for (p in obj)
{
if (obj.hasOwnProperty(p))
//process property
}
This is to avoid using code that iterates over all properties in the prototype chain, possibly dumping the super object.
if (!Object.prototype.hasProperty)
{//dirty check ;-P
Object.prototype.hasProperty = (function(OP)
{
return function(name)
{
//typeof for speed: if value is not undefined, return true
if (typeof this[name] !== 'undefined' || this.hasOwnProperty(name))
return true;
if (this === OP)//we've just checked the Object.prototype, found nothing, so return false
return false;
return Object.getPrototypeOf(this).hasProperty(name);//check prototype
};
}(Object.prototype));//OP is object prototype
}
source to share