The for (i in a)
structure in Javascript lists the properties of a Javascript object that are marked as enumerable
. It lists all enumerable properties of the object whether they are directly on the object or inherited via the prototype. 'enumerable` is a specific characteristic of a property. You can have properties of an object that are enumerable or not enumerable.
The .length
property is not marked as enumerable so it does not show using the for (i in a)
structure. If you create a property yourself with Object.defineProperty()
, you can control the enumerable attribute (along with several other attributes). If you just add a property directly without specifying its custom attributes using Object.defineProperty()
, then the property will be enumerable by default.
For a variety of reasons, you should never attempt to iterate the elements of an Array with the for (i in a)
structure. That structure is explicitly designed to list out the enumerable properties of a Javascript object which will include all Array elements, but may also include other enumerable properties too (as you've seen). Array elements should be enumerated with:
for (var i = 0, len = array.length; i < len; i++) {
// array[i]
}
or
array.forEach(function(val, index, array) {
// code here
});
As for your observation about .clone
, that is not a standard property of an Array object. I'm guessing that it may have been added to the Array prototype by some third party library and it is apparently marked as enumerable which explains why it shows in your for (i in a)
loop.
.hasOwnProperty()
is often used to filter out properties that are on the prototype so you only iterate properties which are applied directly to the object (not inherited from a prototype) which explains why it would filter out the .clone
property (if it was on the prototype).
In any case, if your objective is to iterate the elements of an array (and not any custom properties added to the Array object), then you should use one of the above two methods of iteration and then you won't have to worry about .hasOwnProperty()
or other enumerable properties on the prototype or on the Array object itself.