小白请教一个关于setTimeout的问题?

1.第一种情况,setTimeout的第一个参数写函数名,可以正确执行,并且函数执行有延迟效果
var cards = document.getElementsByClassName('card');
    for(let i=0;i<cards.length;i++){
        setTimeout(show,1000*i);
    }
    //动画
    function show(){
        console.log(new Date());
    }
2.第二种情况,setTimeout的第二个参数函数带参数,可以执行,但是没有延迟效果;
var cards = document.getElementsByClassName('card');
    for(let i=0;i<cards.length;i++){
        setTimeout(show(i),1000*i);
    }
    //动画
    function show(i){
        console.log(new Date());
    }
这是为什么呢?

带参数的写成这样就会有正确的效果

setTime(function(){
    show(i)
},1000*i)

求解答

阅读 4.5k
9 个回答

你这个是把show()的返回值当setTimeout的第一个参数执行
setTimeout(show,1000*i,i);第三个和之后的都是第一个参数的参数

setTimeout(show(i),1000*i);

setTimeout语句执行前,show(i)已经被执行

setTimeout函数要求第一个参数为一个函数

正确的代码:

    var cards = document.getElementsByClassName('card');
    for(let i=0;i<cards.length;i++){
        setTimeout((function(i){
            return function(){
                show(i);
            }
        }(i)),1000*i);
    }
    //动画
    function show(i){
        console.log(new Date());
    }

楼上正解,show(i)在setTimeout语句执行前已经被执行了,它已经是一个结果了,所以setTimeout(show(i),1000i);即为setTimeout(一个结果,1000i);
自然是没有解的,而打印出来的值其实是show(i)执行的结果,所以自然没有延时效果

settimeout(show(),i) 你这表示是执行函数.是函数自己执行.而不是定时器去调用
settimeout(show,i) 这是调用函数. 和传参不传参一点关系没有.

settimeout(function(){

show();

})

这是创建个函数去调用.新创建的函数被定时器调用.所有也会有延迟.

这就是一个函数调用的问题.仔细思考就明白了

关于第二种情况的解释是这样的:
对于javascript,只有在方法真正执行时才会读取所涉及的变量值。像 show(i) 这个方法的i值并非如你所料的依次传参为 0、1、2...然后延时执行。实际发生的情况是,等延时结束开始执行 show方法时,show方法才取读取 i 值 ,而此时它的值应该是 cards.length ,结果出现所有的输出结果都会是相同的值。

彻底理解偏了,楼上 @可好了 的说法是正确的。那是执行函数的用法,是立即执行的。

show柯里化就行啦~

var cards = document.getElementsByClassName('card')
for (let i = 0; i < cards.length; i++) {
  setTimeout(show(i), 1000 * i)
}
//动画
function show(i) {
  return function() {
    console.log(new Date())
  }
}

这跟js语法解析有关,js是解释型语言!在从上到下执行中,碰到了show(i),那么就会立即执行这个函数,所以settTimeout()的第一个参数其实是show()函数的返回结果!

一个很简单的答案,setTimeout的第一个参数是一个函数或者是一个函数的引用,在他内部,当到了需要执行的时间,它会调用第一个参数
function setTimeout(fun,time){

如果到了需要执行的时间-->
fun()

如果你传入一个fun(),那么在内部就是fun()(),如果fun方法没有返回值,那么就相当于只写了一个()

}

setTimeout的第一个参数应该是一个function, 在设置定时的时候首先js解释器会去对show(i)进行求值, 在求值的过程中show的函数体会被立即执行, 然后console.log的返回值为undefined, 然后

> setTimeout(undefined,1000)
TypeError: "callback" argument must be a function

所以呢, 就会出现如题的情形

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题