Search code examples
javascriptobjectprototypehasownpropertyecmascript-2016

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

Solution

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