I've been told not to use for...in
with arrays in JavaScript. Why not?
相关问题
- Is there a limit to how many levels you can nest i
- How to toggle on Order in ReactJS
- void before promise syntax
- Keeping track of variable instances
- Can php detect if javascript is on or not?
Also, due to semantics, the way
for, in
treats arrays (i.e. the same as any other JavaScript object) is not aligned with other popular languages.An important aspect is that
for...in
only iterates over properties contained in an object which have their enumerable property attribute set to true. So if one attempts to iterate over an object usingfor...in
then arbitrary properties may be missed if their enumerable property attribute is false. It is quite possible to alter the enumerable property attribute for normal Array objects so that certain elements are not enumerated. Though in general the property attributes tend to apply to function properties within an object.One can check the value of a properties' enumerable property attribute by:
Or to obtain all four property attributes:
This is a feature available in ECMAScript 5 - in earlier versions it was not possible to alter the value of the enumerable property attribute (it was always set to true).
You should use the
for(var x in y)
only on property lists, not on objects (as explained above).In isolation, there is nothing wrong with using for-in on arrays. For-in iterates over the property names of an object, and in the case of an "out-of-the-box" array, the properties corresponds to the array indexes. (The built-in propertes like
length
,toString
and so on are not included in the iteration.)However, if your code (or the framework you are using) add custom properties to arrays or to the array prototype, then these properties will be included in the iteration, which is probably not what you want.
Some JS frameworks, like Prototype modifies the Array prototype. Other frameworks like JQuery doesn't, so with JQuery you can safely use for-in.
If you are in doubt, you probably shouldn't use for-in.
An alternative way of iterating through an array is using a for-loop:
However, this have a different issue. The issue is that a JavaScript array can have "holes". If you define
arr
as:Then the array have two items, but a length of 101. Using for-in will yield two indexes, while the for-loop will yield 101 indexes, where the 99 has a value of
undefined
.Because it will iterate over properties belonging to objects up the prototype chain if you're not careful.
You can use
for.. in
, just be sure to check each property with hasOwnProperty.It's not necessarily bad (based on what you're doing), but in the case of arrays, if something has been added to
Array.prototype
, then you're going to get strange results. Where you'd expect this loop to run three times:If a function called
helpfulUtilityMethod
has been added toArray
'sprototype
, then your loop would end up running four times:key
would be0
,1
,2
, andhelpfulUtilityMethod
. If you were only expecting integers, oops.