JavaScript输出与我的回答不同

时间:2018-05-25 05:06:46

标签: javascript

在工作面试的采访中,我的问题被记录为错误。

问的问题:这个代码块的输出是什么?

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log('Index: ' + i + ', element: ' + arr[i]);
  }, 3000);
}

我的回答是:

index 0 element 10
index 1 element 12
index 2 element 15
index 3 element 21

但这不正确。什么是正确的答案?

3 个答案:

答案 0 :(得分:3)

这是最受欢迎的javascript访谈问题。

Answer is Index: 4, element: undefined(printed 4 times).

原因是因为setTimeout函数创建了一个可以访问其外部作用域的函数(闭包),该作用域是包含索引i的循环。经过3秒后,执行该函数并打印出i的值,该值在循环结束时为4,因为它循环经过0,1,2,3,4并且循环最终停止在4。 arr [4]不存在,这就是你未定义的原因。

答案 1 :(得分:1)

答案是:

Index: 4, element: undefined
Index: 4, element: undefined
Index: 4, element: undefined
Index: 4, element: undefined

说明:

此处使用

setTimeout打印到控制台,超时为3000毫秒或3秒,到那时for循环将会很长,并且在for的末尾循环,i的值将为4.

由于setTimeout内的函数可以访问变量'i'(名为closure,更多地了解here),因此会打印i = 4的值}。由于arr中没有此类索引4,因此undefined

我希望这可以解除你的怀疑。

答案 2 :(得分:1)

对于使用setTimeOut()函数的答案,您需要使用IIFE - 立即调用的函数表达式。 喜欢这个

const arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  (function(i){setTimeout(function() {
    console.log('Index: ' + i + ', element: ' + arr[i]);
  }, 3000)})(i);
}

因为,对于每个循环,整个内部函数将被执行,然后只有下一个循环运行。否则, setTimeout 函数将创建超时事件,但循环将完成,循环完成后的i值仅为4,并且相应的数组元素不存在。所以,它将是未定义的。

要了解此方案,请参阅以下链接。