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 fromnull
notObject.prototype
- If
hasOwnProperty
has been redeclared onobj
- If
hasOwnProperty
has been redeclared inobj
'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 theNumber
object contains thetoString
property and it doesn't come from its prototype chain (hasOwnProperty).Object.prototype.hasOwnProperty.call(Number, "toString")
is essentially the same asNumber.hasOwnProperty("toString")
- it's not checking the prototype but theNumber
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 thehasOwnProperty
method.
This method can be used to determine whether an object has the
specified property as a direct property of that object; unlike thein
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
How to Add/Subtract Dates with JavaScript
Extending Built-In Natives in Es6 with Babel
Add Onclick Event to Newly Added Element in JavaScript
Why Is Immutability So Important (Or Needed) in JavaScript
What's the Difference Between JavaScript and Jscript
JavaScript - Difference Between Array and Array-Like Object
What Is Browser.Ignoresynchronization in Protractor
App.Settings - the Angular Way
Is It Safe to Assume Strict Comparison in a JavaScript Switch Statement
Facebook How to Check If User Has Liked Page and Show Content
JavaScript to Sort Contents of Select Element
Sum of Two Numbers with Prompt
Jquery.Getjson - Access-Control-Allow-Origin Issue
Need to Cancel Click/Mouseup Events When Double-Click Event Detected