为什么访问给定位置旁边的元素时行为不正确,而访问上一个元素却能正常工作?

时间:2018-09-26 13:09:29

标签: javascript arrays implicit-conversion

给出以下简单的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是哪里来的?

1 个答案:

答案 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 explanationhow to iterate over arrays in JavaScript)。但是,在任何其他应为数字变量实际上拥有字符串值的情况下(例如,在解析文本数据而忘记进行转换时),它也会使您感到痛苦。