Often, developers will use call
on a built-in type to ensure that they are getting the correct native behavior of a method and not some overridden behavior.
It is a protective measure that we really shouldn't have to use, but because Objects are so malleable in JavaScript, it guarantees we get the behavior we desire.
Imagine if someone (who, intentionally or accidentally) created an object like this:
function SuperObject(){
this.foo = function(){
// Something here
};
this.hasOwnProperty = 42;
}
And then, you came along (without having seen the implementation of the object) and wrote:
var mySuperObject = new SuperObject();
console.log("Does 'mySuperObject' instance have its own 'foo' property? " +
mySuperObject.hasOwnProperty("foo"));
You'd get this:
function SuperObject(){
this.foo = function(){
// Something here
};
this.hasOwnProperty = 42;
}
var mySuperObject = new SuperObject();
// Safe way:
console.log("Does 'mySuperObject' instance have its own 'foo' property? " +
{}.hasOwnProperty.call(mySuperObject, "foo"));
// Unsafe way (fails):
console.log("Does 'mySuperObject' instance have its own 'foo' property? " +
mySuperObject.hasOwnProperty("foo"));
So, instead we get code like this:
// This creates a new "fresh" (and unaltered) object with "object literal"
// syntax that you know doesn't override "hasOwnProperty"
{}.hasOwnProperty.call(obj, propKey)
// This performs the same task, but uses the native prototype object
// of the built-in Object type that we also know hasn't been altered:
Object.prototype.hasOwnProperty.call(obj, propKey)
It forces the hasOwnProperty
to be looked up on the prototype chain of the native Object
, while:
obj.hasOwnProperty(propKey)
relies on that property being available and correct on a particular instance of an object (obj
).
Other popular examples of this are with the Array type:
// These work the same as the Object examples above, but just
// do it for the Array type:
[].forEach.call(); // Array literal syntax
Array.prototype.forEach.call(); // Explicit array syntax