【问题标题】:Javascript - For Loop key undefined ONLY for 1st iteration?Javascript - For Loop 键未定义仅适用于第一次迭代?
【发布时间】:2014-03-04 20:35:37
【问题描述】:
为什么数组[j]的第一次迭代总是打印UNDEFINED??
var array = [1,2,3,4,5]
for (i in array) {
console.log("array[i]:" +array[i]);
for (j=i+1; j<array.length-1;j++) {
console.log("array[j]:"+ array[j]);
}
}
【问题讨论】:
标签:
javascript
loops
for-loop
【解决方案1】:
这是因为i 包含一个字符串值,而不是一个数字。
将j 设置为i+1 使其变为"0"+1,而不是0+1,因此是"01"。由于array 中没有带有密钥"01" 的项目,因此您将返回undefined。
当j++被执行时,它会将"01"转换为数字1并增加它,这样循环就会按预期运行到最后。
对于外循环中的下一次迭代,您会得到j = "11",当它与数组的长度进行比较时,它将跳过内循环。对于外部循环中的其余迭代,将跳过内部循环,因为j 将从数组外部开始。
【解决方案2】:
当您在数组上使用foreach 语法时,它实际上是将数组的索引作为字符串值拉入i 变量中。执行j = i + 1 将j 变量设置为字符串值01,array 中的该键没有对应的值,因此它返回 undefined。
在子循环的第一次迭代之后,j++ 会将其转换为整数并在数组的索引处返回正确的值。
有关您使用的foreach 语法的更多信息,请参阅this question。
【解决方案3】:
这是因为您在数组上使用了 for...in 循环。当您使用for...in 时,数组索引被视为哈希键,因此被视为字符串。因此,当您开始第二个循环并将j 设置为i + 1 时,您实际上已将j 设置为“01”。由于没有array["01"],因此您在第一次迭代时会得到未定义。在第二次迭代中,您通过将 j 设置为 length - 1 将其转换回数字,因此可以使用它来访问数组索引。试试这个例子:
var array = [1,2,3,4,5]
for (i in array) {
console.log(typeof i);
console.log("array[i]:" +array[i]);
for (j=i+1; j<array.length-1;j++) {
console.log(j);
console.log("array[j]:"+ array[j]);
}
}
解决此问题的方法是不使用带有数组的for...in 循环。只需坚持正常的for 循环,当然,在需要的情况下也可以使用while 和do 循环。
【解决方案4】:
故事的其余部分
这是答题比赛的迟到。
使用for..of
for ( var i of array) 自动将Array“索引”强制转换为数字 - 因此只需将“in”替换为“of”即可解决 OP 的问题
不要使用for..in
JS 文档说
注意:for...in 不应用于迭代索引顺序很重要的数组。
为什么?当前的所有答案都说问题在于“索引”实际上是字符串。那个怎么样?我们都知道“for 循环”使用数字并且有效。
JS Arrays 不是数组而是普通的 JS 对象
JS 数组实际上是一个变相的普通旧 JS 对象 - 键:值对,其中键(属性名称)始终是字符串。 Array 没有真正的索引! “索引”只是名称为字符串数字的属性,因此“0”、“1”等。没有数字索引。但是你可以说Array 是 JS 对象的一个特例——它使用了无效的名称(以数字开头)并且 JS 允许我们像 Array 实际上有索引一样编写。只是众多 Javascript WTF 中的另一个。