Why Use Object.Prototype.Hasownproperty.Call(Myobj, Prop) Instead of Myobj.Hasownproperty(Prop)

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

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)).

Object.prototype.hasOwnProperty.call() vs Object.prototype.hasOwnProperty()

I would generally always go with obj.hasOwnProperty(prop).

There's less indirection and it'll be much clearer for others trying to read and understand your code. It'll also run slightly faster, because you don't need to rebind the context for this.

I can't think of many pitfalls that would require you to use the other approach.

  • If obj inherits from null not Object.prototype
  • If hasOwnProperty has been redeclared on obj
  • If hasOwnProperty has been redeclared in obj's prototype chain

All of these scenarios are pretty rare in day to day applications and if you do find one of them, it's safest, easiest and best to fix the problem there, rather than use the more defensive Object.prototype.hasOwnProperty.call form.

Practical differences of Object.hasOwnProperty vs Object.prototype.hasOwnProperty

Using Object.hasOwnProperty is weird because it makes it seem like you are using a static method like Object.assign().

It still works because if a property is not found on Object, it falls back to Function.prototype object. And, this object inherits from Object.prototype. So, if you have a custom implementation for Function.prototype.hasOwnProperty, then Object.hasOwnProperty will use that implementation instead of Object.prototype.hasOwnProperty

console.log( Object.hasOwnProperty === Object.prototype.hasOwnProperty ) // trueconsole.log( Object.getPrototypeOf(Object) === Function.prototype ) // trueconsole.log( Object.getPrototypeOf(Function.prototype) === Object.prototype ) // true
Function.prototype.hasOwnProperty = _ => 'custom implementaion in Function.prototype'
const obj = { prop: 10 }
console.log(Object.hasOwnProperty.call(obj, 'prop')) // custom implementaionconsole.log(Object.prototype.hasOwnProperty.call(obj, 'prop')) // true

Why does Object.prototype.hasOwnProperty.call(Number, toString) return false?

You are actually checking two different things:

  • Number.prototype.hasOwnProperty("toString") will check if the prototype of the Number object contains the toString property and it doesn't come from its prototype chain (hasOwnProperty).
  • Object.prototype.hasOwnProperty.call(Number, "toString") is essentially the same as Number.hasOwnProperty("toString") - it's not checking the prototype but the Number object itself.

These are two different objects as can be seen here:

console.log(Number === Number.prototype)

What's the difference between obj.hasOwnProperty() & Object.prototype.hasOwnProperty.call()?

If the obj is not tampered with, there is relatively little difference. But all sorts of stuff can get in the way if you rely on obj containing the prototype function as you expect it to work (potentially even by accident). This is why you'll often see libraries make calls to the prototype methods directly instead of relying on them being in tact on the individual objects.

Consider this case:

const prop = 'test';
obj = {test: 'example'};console.log({ 'version': 'no tampering!', 'obj.hasOwnProperty': obj.hasOwnProperty(prop), 'Object.prototype.hasOwnProperty': Object.prototype.hasOwnProperty.call(obj, prop)});
// someone does something you don't expect with objobj.hasOwnProperty = () => false;// NOTE: This at least is a function, there is nothing to stop me from setting it to something that would BREAK the function call...// E.g. obj.hasOwnProperty = 42;
console.log({ 'version': 'some tampering!', 'obj.hasOwnProperty': obj.hasOwnProperty(prop), 'Object.prototype.hasOwnProperty': Object.prototype.hasOwnProperty.call(obj, prop)});

Are there any cases when I should use the in operator instead of hasOwnProperty()?

Feature detection for loading polyfills, testing conditions for using modern DOM APIs etc.

Using the in operator is ideal for assessing whether you should load/execute a JavaScript polyfill precisely because it checks the prototype chain.

For instance:

// this works wonderfully
if (!('addEventListener' in window)) {
// polyfill addEventListener
}

compared to:

// this doesn't work at all
if (!window.hasOwnProperty('addEventListener')) {
// polyfill addEventListener
}

Hence why the Polyfill.io service uses it for its feature detection tests.

Benefits of calling hasOwnProperty as a direct static reference with the call method, as opposed to calling it as an object instance method

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

Why does hasOwnProperty not recognise functions on an object's prototype?

I think you're confusing a few concepts here. Let's take this quote from the MDN:

Every object descended from Object inherits the hasOwnProperty method.
This method can be used to determine whether an object has the
specified property as a direct property of that object; unlike the in
operator, this method does not check down the object's prototype
chain
.

So that's the key here. When you use new JavaScript will assign a brand new object to this and return it, that's what an instance is. Any property declared inside the constructor is an own property. Properties declared on the prototype are not, since they are shared with other instances of the same object.

And a prototype is also an Object, for example:

Bob.prototype.hasOwnProperty("sayHello"); //=> true

myBob.constructor.prototype.hasOwnProperty("sayHello"); //=> true

What is property in hasOwnProperty in JavaScript?

hasOwnProperty returns a boolean value indicating whether the object on which you are calling it has a property with the name of the argument. For example:

var x = {
y: 10
};
console.log(x.hasOwnProperty("y")); //true
console.log(x.hasOwnProperty("z")); //false

However, it does not look at the prototype chain of the object.

It's useful to use it when you enumerate the properties of an object with the for...in construct.

If you want to see the full details, the ES5 specification is, as always, a good place to look.



Related Topics



Leave a reply



Submit