为什么这个不正确的 JavaScript 程序会产生正确的答案?

Why does this incorrect JavaScript program produce the correct answer?

我在面试中得到了以下 JavaScript 程序。

const average = xs => {
    let sum = 0;
    for (let num in xs) sum += num;
    return sum / xs.length;
};

const result = average([2, 4, 6]);

console.log(result); // 4

面试官让我解释这段代码是如何工作的。我认为 average 函数只是将数组中的所有数字相加,然后将总和除以数组的长度。但是,这不是正确的解释。

以上代码中存在错误。然而,它产生了正确的答案。你能找到错误并修复它吗?另外,你能解释一下为什么上面的代码即使不正确也会产生正确的答案吗?

问题是您使用的是 for...in loop instead of a for...of 循环。 for...of 循环会遍历数组元素,无论输入如何,都会产生正确的答案。但是,for...in 循环遍历数组索引。因此,在大多数情况下,它会产生错误的答案。然而,对于这个特定的输入,它会产生正确的答案。

|  sum   | num |
| ------ | --- |
|  0     | "0" |
| "00"   | "1" |
| "001"  | "2" |
| "0012" |     |

数组的索引为"0""1""2"。索引是字符串,而不是数字。因此,当您将索引 "0" 添加到 sum 的初始值时,即 0,然后 JavaScript 将 sum 转换为字符串,将两者连接起来字符串,并将连接后的字符串存储回 sum。在循环结束时 sum 的值是 "0012" 而不是期望值 12.

然而,"0012" / 312 / 3 都给出了正确的答案,即 4。在第一种情况下,JavaScript首先将字符串"0012"转换为数字12。因此,我们不小心得到了这个特定输入的正确答案。

for...in 用于获取对象中的键。由于 数组是对象的特殊实现,其键作为数字索引,因为...在 returns 这些键中。

键为“0”、“1”、“2”[​​=12=]

每次迭代后 字符串连接 发生“0”+“0”+“1”+“2” 总和=“0012”

当您尝试除此时,它会隐式转换为数字 12/3=4

所以输出结果为 4。

您可以在以下代码片段中查看此内容

let xs = [2,4,6], sum=0 
for (let num in xs) { sum += num; console.log(num,sum); }