翻阅MDN,可以发现setTimeout不仅支持第三个参数,甚至更多参数
var timeoutID = scope.setTimeout(function[, delay, arg1, arg2, ...]); var timeoutID = scope.setTimeout(function[, delay]); var timeoutID = scope.setTimeout(code[, delay]);
看以下例子可以知道,代码运行为6次打印了6。因为setTimeout因为是一个异步函数,var变量存在变量提升、无块级作用域等,等执行到setTimeout时,for循环已经遍历结束,i的值已经是6。
for (var i = 0; i < 6; i++) { setTimeout(() => { console.log(i) }, 1000) }
解决办法
1、闭包;使用闭包将i的值驻留在内存中,打印j的值(形成了自己的作用域),实际的外部函数的变量i
for (var i = 0; i < 6; i++) { (function (j) { setTimeout(() => { console.log(j) }, 1000) })(i) }
2、setTimeout的第三个参数,该参数就是给setTimeout第一个函数的参数。每次传入setTimeout第一个函数的j值是for遍历的值,个人认为还是作用域的问题。
for (var i = 0; i < 6; i++) { setTimeout( (j) => { console.log(j) }, 1000, i ) }
第三个及以后的参数都可以作为show函数的参数
function show(x, y, z) { console.log(x, y, z) } setTimeout(show, 100, 1, 2, 3)