How to avoid for...in eslint issues?

Viewed 7176

I have an object with some keys and values.

I initially had this loop:

  for(const key in commands) {
    if (commands.hasOwnProperty(key)) {
      const value = commands[key];
      // Do something else
    }
  }

That gave me the following eslint error:

for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array. (no-restricted-syntax)

So I changed it to this:

  Object.keys(commands).forEach(key => {
    if (commands.hasOwnProperty(key)) {
      const value = commands[key];
    }
  });

Now, I'm getting the following error due to hasOwnProperty:

Do not access Object.prototype method 'hasOwnProperty' from target object. (no-prototype-builtins)

How can I write a simple loop that iterates over the keys whilst avoiding eslint errors?

3 Answers

When using Object.keys, you do not need to check hasOwnProperty. Object.keys produces an array of exclusively own properties. This is why the first eslint error was recommending that you use it.

For the second lint error, it's recommending that you do

Object.prototype.hasOwnProperty.call(commands, key)

The reason this lint rule exists is that it's possible for commands.hasOwnProperty to be undefined, if commands was created using Object.create(null). In your case though, you just need to delete the check:

Object.keys(commands).forEach(key => {
  const value = commands[key];
  // Do something else
});

First of all, you can disable the eslint rule if you don't need it. As it states, for...in will iterate over inherited properties, so it was often used in combination with hasOwnProperty, but the new Object.keys syntax is shorter.

Second, you don't need hasOwnProperty if you're using Object.keys. It only iterates over own properties already.

Third, eslint doesn't like you using hasOwnProperty on an object, because it can be reassigned to be a different function. I guess it wants you to use Object.prototype.hasOwnProperty.call(object, key) if you really need it, but I'd argue that there are plenty of cases where you know it's safe to use the shorter version. Again, you can disable the rule if you know the implications.

Object.keys() only collects the object's own properties. No need to do a hasOwnProperty check for it. Removing it would fix the issue of the second snippet.

If you know what you're doing/prefer for-in anyways, you can always add //eslint-disable-next-line the line before the line that's causing the errors to disable eslint warnings for that line alone.

Related