A slightly modified test case very well exposes the problem:
$ cat test.js
var a = [ 1, 2, 3 ]
for ( var i in a ) {
console.log(i-1, i, i+1);
console.log(a[i-1], a[i], a[i+1]);
console.log('--------');
}
$ nodejs test.js
-1 '0' '01'
undefined 1 undefined
--------
0 '1' '11'
1 2 undefined
--------
1 '2' '21'
2 3 undefined
--------
So, the variable i
is of string type. When using it to access the previous element, Javascript being a weakly typed language, the interpreter figures out that the expression i-1
makes sense only if i
is converted to a number. To keep things fair (and programmers' lives interesting), in the expression i+1
the interpreter converts 1
to a string and treats +
as concatenation, producing a key that is missing from the array (or, if the array were long enough, a wrong element would be accessed: a[11]
instead of a[2]
, a[21]
instead of a[3]
, etc).
In this particular case the problem comes from the incorrect way of looping over the array (if the answer to this question was not obvious to you then carefully read the excellent explanation of how to iterate over arrays in JavaScript). However it can bite you in any other situation where a variable that is supposed to be numeric actually holds a string value (for example, when parsing text data and forgetting to do the conversions).