在工作面试的采访中,我的问题被记录为错误。
问的问题:这个代码块的输出是什么?
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
但这不正确。什么是正确的答案?
答案 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,并且相应的数组元素不存在。所以,它将是未定义的。
要了解此方案,请参阅以下链接。