SetInterval和SettimeOut(转载文章)

 

学过JavaScript 脚本语言的都应该接触过setInterval 函数.如何使用我想大家都知道,但是有时候还是会在使用的时候碰到这样或那样的问题。下面的问题也是在QQ群经常碰到有人问的最多的,问题如下图:
 


首先声明:本人技术水平很低,以下所诉完全是依照自己的理解来做一些说明。如果有不当之处,还请批评斧正!以下仅仅是对自己理解,就当完事扯蛋吧!其内容都非常浅显,聊的多了自己也搞不定了!因为真的怕扯蛋扯疼了!

      在JavaScript中的setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数来将其停止。

其实提上对函数的调用均能执行。首先我们看以下代码

[HTML] 纯文本查看 复制代码运行代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
      function fun() {
            alert(1);
        }
        setInterval("fun()",1000);//全局作用域下正常执行
        setInterval(fun(),1000); //调用函数正常,setInterval调用出错
        setInterval(fun,1000);  //正确
    </script>
</head>
<body>
 
</body>
</html>


    我所给出的代码和提问题人是一样的,唯一的区别就是函数名不同罢了!如果大家做了相关测试都应该知道,就以上代码来说都会弹出结果1.
当然以上代码其执行环境为全局。setInterval 第一个参数 可以是函数名、匿名函数、函数的引用以及其他可执行代码。

[JavaScript] 纯文本查看 复制代码运行代码
1
setInterval("fun()",1000);


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

[JavaScript] 纯文本查看 复制代码运行代码
1
setInterval(fun(),1000);


而这个调用我就不理解使用者通过这种方式使用setInterval 的意图为何.
fun() 是对函数的直接调用,也就是说当setInterval还没有开始函数func就执行了。如果这个函数没有返回值或者返回值不是可执行的函数或者其他的代码的话,就以上代码而言只是弹出1,之后就遍报错了.
难道这样的调用真的不可以吗?其实是可以的!例如代码:

[JavaScript] 纯文本查看 复制代码运行代码
1
2
3
4
5
6
      function funone() {
          return function () {
            alert("qishiwoyenengzhixing")
          }
      }
setInterval(funone(), 1000);//你敢说我不能执行?


我个人认为这种设计或者调用完全没有任何意义,用其他的方法就行了。
--------------------------------------------------------------------------------------------------------------

[JavaScript] 纯文本查看 复制代码运行代码
1
setInterval(fun,1000); //这种方法是正确的。


大家可以把这种调用setInterval的第一个参数看作参数为 函数名或函数的引用。当然我们还可以这样调用,使用匿名函数。

[JavaScript] 纯文本查看 复制代码运行代码
1
2
3
4
setInterval(function () {
 
            alert("我一秒中执行一次");
        }, 1000)


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

有些人可能发现,在全局作用域下  setInterval("fun()",1000); 可以正常执行,但放到window.onload函数中却不能执行。为什么呢?
先请看代码:

[JavaScript] 纯文本查看 复制代码运行代码
1
2
3
4
5
6
7
8
9
window.onload = function () {
            function fun() {
                alert(1);
            }
             setInterval("fun()",1000);//这个报错了 未定义   重点在这一个
            // setInterval(fun(), 3000); //这个和刚才全局的表现一样
           // setInterval(fun,1000);//这个没有问题
 
        }


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

对与setInterval(fun(), 3000)和setInterval(fun,1000)调用其执行I环境并没有改变,所以是可以访问的到的。只不过setInterval(fun(), 3000)执行后 会报错的,其调用错误。在之前已经讲过了,这里就不啰嗦了!

------------------------------------------------------------------------------------------------
为了让大家明白 setInterval("fun()",1000)  的调用是以可执行代码 执行。给出以下代码共大家测试:

[JavaScript] 纯文本查看 复制代码运行代码
1
2
3
4
function fun() {
            alert(1);
        }
        setInterval("alert(fun)",2000);



[JavaScript] 纯文本查看 复制代码运行代码
1
setInterval("var a=1;var b=2;c=a+b;alert(c);",1000); //大家说这个会是什么呢 ?
posted @ 2016-03-26 11:01  沐柶  阅读(138)  评论(0编辑  收藏  举报