This is a well known issue with Javascript's for..in
loops.
You may think you're just looping through the elements of an array or an object that you've added directly, but it will also loop through any methods in the prototype as well. This can have unexpected consequences.
There are two ways around it:
Firstly, for arrays, don't use for..in
. Use a simple for()
loop instead -- ie:
for(var counter=0; counter<myArray.length; counter++) {...}
This form is recommended for arrays, because it is guaranteed to only iterate through the numeric array elements.
It doesn't work for generic objects, of course, since they don't have a length
property nor numeric elements. For these, you still need to use for..in
, but you should also always include an if()
statement inside a for..in
loop to filter out unwanted elements.
The format of this should look like this:
for (name in obj) {
if (obj.hasOwnProperty(name)) {
...
}
}
This looks ugly, but because of the problems of not doing it, it is recommended best-practice for Javascript, to the point that JS code quality cheking tools such as JSLint and JSHint will flag it up as a problem if you don't write your for..in
loops like this.
You can read more about this problem here: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/