JavaScript中setInterval函数应用常见问题之一(第一个参数不加引号与加引号的区别)

     学过JavaScript 脚本语言的都应该接触过setInterval 函数.如何使用我想大家都知道,但是有时候对于刚刚接触JavaScript的朋友来讲,还是会在使用的时候碰到这样或那样的问题而感到困惑!以下是经常在QQ群中碰到问的最多的问题。如下图:

 

首先声明:本人JavaScript技术水平较低,以下所诉完全是依照自己的理解来做一些说明。如果有不当之处,还请批评斧正!以下就全当是在扯蛋吧,扯的很显浅,
扯深了自己搞不定,还会扯疼的!

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

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

   <!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 第一个参数 可以是函数名、匿名函数、函数的引用以及其他可执行代码。(个人理解)

 setInterval("fun()",1000);

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

   setInterval(fun(),1000);

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

           function funone() {
            return function () { 
              alert("qishiwoyenengzhixing");
            }
        }
  setInterval(funone(), 1000);  //每隔一秒钟都会弹出 qishiwoyenengzhixing 你信不信,反正我信了

就我个人认为这种设计或者调用完全没有任何意义。在此只做一下简单的说明吧!

setInterval(fun,1000); //这种方法是正确的。

大家可以把这种调用setInterval的方式的第一个参数看作参数为 函数名或函数的引用。当然还可以直接使用匿名函数,如:

setInterval(function () {

            alert("我一秒中执行一次");
        }, 1000);

  有些人刚接触JavaScript可能发现,在全局作用域下  setInterval("fun()",1000); 可以正常执行,但放到window.onload函数中却不能执行。为什么呢?(其实一开始我也碰到了相同的问题)

 

代码如下:

window.onload = function () {
            function fun() {
                alert(1);
            }
             setInterval("fun()",1000);//这个报错了 未定义   重点在这一个
            // setInterval(fun(), 1000); //这个和刚才全局的表现一样
           // setInterval(fun,1000);//这个没有问题
           
        };

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

对于setInterval(fun(), 1000)和setInterval(fun,1000)的调用其执行环境并没有改变,所以是可以访问的到的window.onload下声明的函数。只不过setInterval(fun(), 1000)执行fun函数后 会报错的,setInterval其调用错误。为什么错误?在之前已经讲过了,这里就不啰嗦了!

 

为了证明自己的的理解为第一个参数加引号 以“可执行代码” 执行。以下是自己写的两段代码进行的测试:

function fun1() {
            alert(1);
        }
        setInterval("alert(fun1)",2000);//你认为结果是多少?
 setInterval("var a=1;var b=2;c=a+b;alert(c);",1000); //这个呢?

 

 

以上内容是个人的理解,因为自己在之前也碰到了相同的问题!也许仅仅对于刚学JavaScript的朋友有一点帮助。当然可能存在错误(包括错别字),欢迎各位大牛批评斧正!。如果你有意帮助本人提高,请留下你宝贵的建议。请不要因此进行谩骂(其实完全可以把此作为一个笑话)!谢谢!

 

 

 

 

 

 

 

 

 

 

 

posted @ 2013-05-19 00:28  bluescreen  阅读(2834)  评论(4编辑  收藏  举报