1

Looking through some of our app code I found the following:

for (prop in aBunchOfData.properties) {
  if (!aBunchOfData.properties.hasOwnProperty(prop)) continue;
  doABunchOfProcessing(aBunchOfData.properties[prop]);
}

As far as I understand, for ... in will only loop through the "own" properties of an object. Can the hasOwnProperty check here ever make a difference? If so, under what conditions?

Thanks!

Bharata
  • 13,509
  • 6
  • 36
  • 50
Gershom Maes
  • 7,358
  • 2
  • 35
  • 55

2 Answers2

5

No. The in operator ascends the prototype chain, while .hasOwnProperty() does not. Using that if statement ensures that only properties on the object itself will be included. To avoid having to use the check, you can use Object.keys(), which does not ascend the prototype chain.

jhpratt
  • 6,841
  • 16
  • 40
  • 50
  • 2
    Just to elaborate, `in` iterates all _enumerable_ keys, and `Object.keys()` iterates all _own enumerable_ keys. Neither iterates non-enumerable keys, though `.hasOwnProperty()` will return `true` for own, non-enumerable keys. – Patrick Roberts Jul 11 '18 at 18:45
  • Thanks Patrick, your mention of enumerability clarified it! I was looking at all these answers thinking "I've iterated over `Object` instances a million times without `hasOwnProperty`, and I've never seen `toString`, `valueOf`, etc, pop up" – Gershom Maes Jul 11 '18 at 18:48
  • @GershomMaes To tack on even more, on the off chance you have `Symbol` keys, they aren't enumerable either, which provides a _minimal_ layer of safety. – jhpratt Jul 11 '18 at 18:50
1

It is useful because a for in loop will check all object properties including prototype props. This is inefficient so checking hasOwnProperty limits the loop to properties that are unique to that object. The preferred way to loop is:

Object.keys(myObject).forEach(()=> // do stuff)

map can also me used as an iterator here.

jmargolisvt
  • 5,722
  • 4
  • 29
  • 46
  • Can `map` be used as an iterator though? I feel like that wouldn't work, as `Object.keys()` _creates_ an array, though I could be wrong on that. – jhpratt Jul 11 '18 at 18:55
  • 1
    If you're referring to what gets mutated, there is more to that story, yes. But you can definitely map over the array that results from `Object.keys()`. – jmargolisvt Jul 11 '18 at 19:01