关于SetInterval(code,time)的第一个参数的几种用法详解

开端

在最近理解的JS任务执行先后以及进程、线程、单线程、多线程的时候遇到一个问题,setInterval和setTimeout这种延时操作是在主函数代码执行后再执行,上代码1

<script>
    for (var i = 0; i < 10; i++) {

        setTimeout((function (j) {

            return function () {
                console.log(j);
            }
        })(i),10);

        console.log("----");
    }

</script>

这种在定时器中调取闭包的方法是为了把每一次的i都按0-9遍历出来。

那么以下这样写跟上面的代码是一样吗?代码2

<script>
    for (var i = 0; i < 10; i++) {

        setTimeout((function (j) {

            //return function () {    不按常规闭包形式返回函数体
                console.log(j);
            //}
        })(i),10);

        console.log("----");
    }

</script>

想不到吧!

那么接下来要说说SetInterval(code,time)的第一个参数传入不同值得不同形式(SetTimeout同理)

    正常来讲我们在定时器中第一个参数肯定是回调函数,自然而然就是function类型,代码1也很正常按着js的任务处理优先级,先处理for循环及for循环里面的任务代码,再处理定时器或者点击事件等操作,so,结果自然是先10个“________”然后再定时器。

    在代码2中,return返回出来的不是一个函数,而是一个代码段,那么很明显违背了定时器的初衷第一个函数为function,在浏览器的结果看来,这个定时器是失效了,就简单认为是一个普通的代码段运行没有定时器的效果。

-------------------------------------

以下是总结了一些网上的案例去分析定时器第一个参数的种种问题

分三种情况

function fun(){
   alert(1);
}

setInterval(fun,1000); 
 //正确

setInterval(fun(),1000);
 //调用函数正常,setInterval调用出错

setInterval("fun()",1000);
 //全局作用域下正常执行

第一种毋庸置疑,第一个参数就是一个函数

第二种写法就是跟上面代码2一样的道理,定时器已经失效,具体是什么原因我也不能道其然

第三种写法就特殊了,其中这种加引号的调用就可以理解为可执行代码,就想eval(动态执行代码)一样去执行第一个参数,就是对fun方法的调用 理所当然的弹出 1,一秒钟间隔,一直执行。

eval("console.log(1);");   //1

定时器中的第一个函数加上双引号,就相当于eval的动态执行代码,直接运行。

拓展

关于定时器中“fun()”

window.onload = function(){
    function fun(){
      alert(1);
    }

    setInterval(fun,1000); 
    //正确

    setInterval(fun(),1000);
    //调用函数正常,setInterval调用出错

    setInterval("fun()",1000);
    //报错fun()未定义
}

setInterval("fun()",1000); 这种调用报未定义,在全局我们已经说过了 。我们可以把带引号的参数理解为 可执行代码 。

而setInterval现在把以引号包括的可执行代码进行处理。就像eval一样给予执行。其在执行中 fun() 执行环境发生了变化,不是在window.onload方法下,而是在全局环境中也就是window.大家应该知道JavaScript存在作用域链,由内向外依次查找。内部可以访问其上层的函数和变量,而外部却不能访问内部的函数和变量。JavaScript有一个预编译处理,首先对函数和变量进行预编译。也就是说其函数和变量作用域是在其声明的时候确定的,而不是在执行的时候确定。当setInterval把"fun()"执行环境换为全局(详细见:拓展)的后,对fun的调用是无效的。因为全局不能访问局部的函数和变量。window.onload相对于window来说就是局部的。

setInterval("var a=1;var b=2;c=a+b;alert(c);",1000);//如果你看完上面内容,这里的答案呼之欲出

 

转载于:https://my.oschina.net/u/2949632/blog/841371

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值