2

In numerous JavaScript sources, I have seen a preference of calling Object.prototype.hasOwnProperty from a static reference as in the following example:

var hasOwnProp = Object.prototype.hasOwnProperty;
//...
if ( hasOwnProp.call(myObj, 'prop') ) {
    doSomethingWith(myObj);
}

Why is it preferred over calling an object instance's hasOwnProperty method:

//...
if ( myObj.hasOwnProperty('prop') ) {
    doSomethingWith(myObj);
}
kzh
  • 19,810
  • 13
  • 73
  • 97

4 Answers4

5

Because you can make an object that looks like this:

var obj = {
    hasOwnProperty: function () {
        throw new Error("you are ugly");
    }
};

ie. you can accidentally, or intentionally redefine the function.

Source on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#hasOwnProperty_as_a_property

Halcyon
  • 57,230
  • 10
  • 89
  • 128
0

Performance. Or at least possibly performance.

The hasOwnProperty method is attached directly to Object.prototype, so when one calls {}.hasOwnProperty('foo'), the JavaScript engine first checks the object directly for a hasOwnProperty method, and if it does not exist there, it goes up the prototype chain again, to check if it exists one level up. Rinse. Repeat.

In the example given in this answer, the JS engine only goes on level up, since the object in question was an object literal. If you were test this on a constructed instance, such as a Date object, then there are more levels up the prototype chain the engine must traverse to get the appropriate method. This is not much of a performance hit for most objects, and in fact for object literals, it more performant on some engines to use the instance method as opposed to the statically called function, but if Object.prototype is several layers above an object ancestrally in the prototype chain, then the performance hit becomes more measurable.

@Frits van Campens's answer does not hold water, however, because one could also override Object.prototype.hasOwnProperty.

Community
  • 1
  • 1
kzh
  • 19,810
  • 13
  • 73
  • 97
  • If you just want performance you can do `var hOP = obj.hasOwnProperty` and call `hOP()`, so that is not the reason. Overriding `Object.prototype.hasOwnProperty` means you're executing code. Iterating over a data object is not quite the same. But hey, don't take my word for it: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty#hasOwnProperty_as_a_property – Halcyon Jul 26 '13 at 20:17
  • 1
    You can't call `hop` directly there, because the `this` context would be window. You would have to call `hop.call(context, prop)`. – kzh Jul 26 '13 at 21:05
0

Besides using Object.prototype.hasOwnProperty, we can also use the object literal ({}).hasOwnProperty.call(myObj, 'prop');

0

Because hasOwnProperty is a function thus it can be redefined and also because when simply called on the object it doesn't look on the prototype chain for that property, but calling it on the prototype will do it.

Avram Tudor
  • 1,468
  • 12
  • 18