I've searched a lot on Google but couldn't found where I was looking for:
Benefit of using Object.hasOwnProperty vs testing if Property is undefined
jsperf speedtest
How to determine if Native JavaScript Object has a Property/Method?
.. and a lot of other websites, but this is not where I am looking for. My real question is:
Why does hasOwnProperty not find a method in his super class(prototype)? And why does somebody even use hasOwnProperty? It's much slower than typeof and it doesn't work if you are working with inheritance.
.. second question:
In this question Barney answers that you have to use if ('property' in objectVar) to check if a property exists, but doesn't explain why. Does someone knows 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());
}
Check out the jsFiddle
There are a number of reasons why one uses (and in some cases has to use) hasOwnProperty, and why its behavior is what it is:
hasOwnProperty checks if the object on which you test owns a property with a given name. If it has inherited a method/property from another object (its prototype), then the owner of that property is not the object, but its prototype. Therefore, the object doesn't have its own property called Xtypeof will work most of the time, but an object can look like this: var o = {foo: undefined}. Using typeof on o.foo will yield "undefined", of course, but the object does own a property called fooif ('properyname' in object) is a workaround, that combines the best of both worlds: in case of o = {foo: undefined}; it will evaluate to true, without the overhead of a lookup for the hasOwnPropery method (which is a property of Object.prototype), or a function call with context binding and all that. It will also find properties in the prototype chainSo consider these 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 thing to note is that your statement about hasOwnProperty not working when dealing with inheritance is just plain wrong. Every object you use in JS inherits from at least one prototype. It is important to realize, understand and respect this. If you loop over an object, it is recommended to make sure you're actually iterating over the properties that belong to the object itself. Hence, this is not uncommon to see:
for (p in obj)
{
if (obj.hasOwnProperty(p))
//process property
}
This is to avoid having code that iterates over all properties in the prototype chain, an possibly mucking up 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
}
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