admin管理员组

文章数量:1356947

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

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

Share Improve this question edited May 23, 2017 at 10:32 CommunityBot 11 silver badge asked Oct 20, 2014 at 8:15 GuyTGuyT 4,4362 gold badges19 silver badges34 bronze badges 1
  • 2 typeof and hasOwnProperty are not related. The in operator is used to check for properties in the prototype chain, while hasOwnProperty checks only directly on that object. If you care about performance with typeof/hasOwnProperty, the fastest way is probably to simply use the evaluated value (since undefined evaluates to false), e.g. if(test.alertMessage) – Johan Commented Oct 20, 2014 at 8:21
Add a ment  | 

1 Answer 1

Reset to default 10

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:

  • As the name suggests, 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 X
  • typeof 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 foo
  • using if ('properyname' in object) is a workaround, that bines 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 chain

So 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 remended to make sure you're actually iterating over the properties that belong to the object itself. Hence, this is not unmon 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
}

本文标签: prototypal inheritanceJavaScript hasOwnProperty vs typeofStack Overflow