javascriptrequirejsprototypal-inheritancehasownproperty

Why use Object.prototype.hasOwnProperty.call(myObj, prop) instead of myObj.hasOwnProperty(prop)?


If I understand correctly, each and every object in JavaScript inherits from the Object prototype, which means that each and every object in JavaScript has access to the hasOwnProperty function through its prototype chain.

While reading RequireJS' source code, I stumbled upon this function:

function hasProp(obj, prop) {
    return hasOwn.call(obj, prop);
}

hasOwn is a reference to Object.prototype.hasOwnProperty. Is there any practical difference to writing this function as

function hasProp(obj, prop) {
    return obj.hasOwnProperty(prop);
}

And since we are at it, why do we define this function at all? Is it just a question of shortcuts and local caching of property access for (slight) performance gains, or am I missing any cases where hasOwnProperty might be used on objects which don't have this method?


Solution

  • Is there any practical difference [between my examples]?

    The user may have a JavaScript object created with Object.create(null), which will have a null [[Prototype]] chain, and therefore won't have hasOwnProperty() available on it. Using your second form would fail to work for this reason.

    It's also a safer reference to Object.prototype.hasOwnProperty() (and also shorter).

    You can imagine someone may have done...

    var someObject = {
        hasOwnProperty: function(lol) {
            return true;
        }
    };
    

    Which would make a hasProp(someObject) fail had it been implemented like your second example (it would find that method directly on the object and invoke that, instead of being delegated to Object.prototype.hasOwnProperty).

    But it's less likely someone will have overridden the Object.prototype.hasOwnProperty reference.

    And since we are at it, why do we define this function at all?

    See above.

    Is it just a question of shortcuts and local caching of property access for (slight) performance gains...

    It may make it quicker in theory, as the [[Prototype]] chain doesn't have to be followed, but I suspect this to be negligible and not the reason the implementation is why it is.

    ... or am I missing any cases where hasOwnProperty might be used on objects which don't have this method?

    hasOwnProperty() exists on Object.prototype, but can be overridden. Every native JavaScript object (but host objects are not guaranteed to follow this, see RobG's in-depth explanation) has Object.prototype as its last object on the chain before null (except of course for the object returned by Object.create(null)).