Gothdo Gothdo - 1 month ago 7
Javascript Question

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

In JavaScript the

in
operator checks whether an object has the specified property. However, it doesn't check only object's own properties, but also the prototype chain. Therefore in some situations it may behave not exactly as expected.

Let's say that for some reason we have an object
someArrayMethods
containing (obviously) some array methods as keys:

const someArrayMethods = {
indexOf: true,
map: true,
};


We can check if that object has a specific method as a key using the
in
operator:

console.log('indexOf' in someArrayMethods); // true
console.log('every' in someArrayMethods); // false


What if we tried to check for
toString
property?

console.log('toString' in someArrayMethods); // true


Surprise! It turns out that this object has a
toString
method
in the prototype chain, so the
in
operator returns
true
even though the object doesn't have its own
toString
property.

And here's where
hasOwnProperty()
comes to the rescue! It's almost the same as the
in
operator, with one difference: it doesn't check the prototype chain. We can rewrite our previous example:

console.log(someArrayMethods.hasOwnProperty('toString')); // false


Now it works as expected. Unfortunately,
hasOwnProperty()
also can fail in one case. What if we had an object with an own property
hasOwnProperty
? See this example:

const someObject = {
hasOwnProperty() {
return false;
},
theAnswer: 42,
};

// Does `someObject` has own property `theAnswer`?
console.log(someObject.hasOwnProperty('theAnswer')); // false
// Well, it seems it doesn't...


To solve this problem, instead of using
someObject.hasOwnProperty
, we can refer to that method directly from
Object.prototype
:

const hasOwn = Object.prototype.hasOwnProperty;
console.log(hasOwn.call(someObject, 'theAnswer')); // true


This seems to be the most reasonable approach for checking if an object has some property. Despite this, are there any cases where the
in
operator would be useful
? I know that it can be used to check if an instance of some class has some method, but in this case isn't it better to simply check if that object is an instance of that class?




As a side note, another option is to use
Object.keys()
with ECMAScript 2016
Array.prototype.includes()
:

console.log(Object.keys(someObject).includes('theAnswer')); // true

Answer

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

Comments