问题复现
var arr = ['a', 'b', 'c'];var sid = ['Go'];for (var key in arr) { sid[key + 1] = arr[key];}console.log(sid)
很简单的问题,最后的输出结果却是:
[ 'Go', , , , , , , , , , , 'b', , , , , , , , , , 'c' ]
问题分析
通过上面的输入结果我们可以发现这么几个问题:
sid
里面多了很多空项,length
明显的增多了arr[0]
的值在sid
中没有出现
问题1:sid
里面多了很多空项,length
明显的增多了
略过痛苦的分析步骤直接来重点内容:
通过打印key + 1
我们可以找到问题的关键。通过打印我们可以得到如下信息。在第一次循环的时候key + 1
的值为01
,此后依次为:11
,21
。通过这个我们可以判断: 这个key
其实是一个String
类型的。所以上面的步骤相当于: sid['01'] = arr[0];sid['11'] = arr[1];sid['21'] = arr[2];
究其原因,我只能在浅层面作出解释:
这可能是因为for-in
一般是用于对象的(狭义的对象),而对象的属性是一个String
类型,所以for-in
的参数key
被定义为一个String
类型。这并没有考虑过数组的属性名(下标)不是String
类型,而是一个Number
类型的情况。所以就出现了上面的问题。此外在关于for-in
这块出现过这样的提示: Note: for..in 不应该被用来迭代一个下标顺序很重要的 Array .
可能就包含这种情况吧。
问题2:arr[0]
的值在sid
中没有出现
arr[0]
的值其实通过sid['01']
可以取到。
node
下打印sid
的时候可能与在console
中打印出现不同的结果。 问题解决
对于数组的遍历,最好使用:forEach
,map
,some
,filter
,find
等方法。尤其是是这种牵扯到数组下标的尽量不要使用for-in
来处理,如果非要使用可以做如下处理:
var arr = ['a', 'b', 'c'];var sid = ['Go'];for (var key in arr) { sid[parseInt(key) + 1] = arr[key];}console.log(sid)
以避免如上的问题。