What is the danger of using for .. in for an object or an array?

    2 answers 2

    For the object:

    • All keys are enumerated, including inherited:

      var obj = {a: 9}; Object.prototype.myAwfulThing = 8; for (var key in obj) { console.log(key); } 

      At the same time, an inherited property can be added by some library.

      Therefore, it is recommended to check for the presence of a property in the object itself:

       var obj = {a: 9}; Object.prototype.myAwfulThing = 8; for (var key in obj) { if (obj.hasOwnProperty(key)) { console.log(key); } } 
    • Even if you are 100% sure that there are no inherited properties, you don’t use any libraries and everything works fine, the browser doesn’t know about it.

      The browser optimizes only the case when there is a check for hasOwnProperty .
      Something this item did not want to be confirmed experimentally.

    For an array:

    • Not only indexes will be moved, but other properties as well. If instead of an array there is an array-like object, then the length property can be caught.

    • If polyfiles for arrays are connected (which is very likely), in browsers that do not know how to make hidden properties, all these functions will be exhausted.

    • Only indexes that are in the array are searched. If the array element was deleted via delete, or the addition to the array occurred by index after its end, then the missing indexes will be skipped. But the order of enumerated indexes will be correct.

       var a = [undefined, , 4]; a[7] = undefined; for (var i in a) { // 0 2 7 console.log(i); } 
    • Bridging an array through for in is inferior in performance to a normal cycle tenfold.

    ES6

    • To iterate over array elements (values, not indexes!), ES6 introduces a for for loop:

       var a = [undefined, , 4]; a[7] = undefined; for (var x of a) { console.log(x); } 

      2 times is displayed undefined , then 4 and 5 more times undefined .

      As written in mdn

      Pass through the array and for ... in

      Note : for...in should not be used for Array , where index order is important.

      Array indices are enumerated properties with integer names, but otherwise are similar to the properties of objects. There is no guarantee that for...in will return the indices in the correct order and will return all enumerated properties, including those with non-integer names and inherited.

      Therefore, the order of the passage depends on the implementation; passage through the array may not occur in the correct order. Therefore, it is better to use for , Array.prototype.forEach () or for ... of loops with numeric indexes when we go through arrays where the order of access to properties is important.

      • Well, the translation they have there! “Per and numeric properties, including those with noninteger numbers ” - VladD
      • @VladD, slightly corrected - Grundy
      • There is a “edit” button, by the way :) - VladD
      • @VladD, in mdn? :) - Grundy
      • Yeah, where else ? :) - VladD