给出以下简单的Javascript代码片段:
var a = [ 1, 2, 3 ]
for ( var i in a ) {
console.log(a[i-1], a[i], a[i+1]);
}
为什么会在下面产生奇怪的输出?
undefined 1 undefined
1 2 undefined
2 3 undefined
第一行的第一个undefined
和最后一行的最后一个undefined
是由于越界访问。但是其他两个undefined
是哪里来的?
答案 0 :(得分:2)
一个稍微修改的测试用例很好地揭示了问题:
$ 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
--------
因此,变量i
是字符串类型。当使用它来访问前一个元素(Javascript是一种弱类型语言)时,解释器会指出,只有将i-1
转换为数字后,表达式i
才有意义。为了保持公平(并使程序员的生活变得有趣),解释器在表达式i+1
中将1
转换为字符串,并将+
视为串联,从而产生数组中缺少的键(或者,如果数组足够长,则会访问错误的元素:a[11]
代替a[2]
,a[21]
代替a[3]
,等等)。
在这种特殊情况下,问题出在数组上的循环方式不正确(如果您对这个问题的答案不明显,那么请仔细阅读excellent explanation的how to iterate over arrays in JavaScript)。但是,在任何其他应为数字变量实际上拥有字符串值的情况下(例如,在解析文本数据而忘记进行转换时),它也会使您感到痛苦。