超时调用与间歇调用

1.首先要清楚,JavaScript是单线程语言,一段时间内只能执行一段代码。因此就有一个JavaScript的任务队列来控制代码的执行顺序。window对象的属性setTimeout()的第二个参数就是告诉JavaScript再过多长时间将当前任务添加到队列中。如果队列是空的,那么添加的代码会立即执行;如果队列不是空的,那么先等到前面的代码执行完后再执行。间歇调用setInterval()与超时调用相似,只不过是重复调用。

 setTimeout(function(){
      alert("Hello");
  },1000);

//setTimeout()与setInterval()的第一个参数可以是函数,也可以使字符串,但是不建议使用字符串,因为代码包裹在字符串中需要二次解析会导致性能问题。还会引起作用域问题

   var name="liu";
   function sayName(){
      var name="liuliu";

      setTimeout("alert(name)",1000); //字符串形式 liu

   }
   sayName();

//////////////////////////////////////////////////   

var name="liu";
   function sayName(){
      var name="liuliu";

      setTimeout(function(){
          alert(name);
      },1000); //函数形式 liuliu
   }
   sayName();

 

2.超时调用和间歇调用都返回一个标识符,可以用于取消调用,clearTimeout()与clearInterval()。一般只有间歇调用需要取消调用操作,不然会重复下去。在实际中一般使用超时调用模拟间歇调用,因为间歇调用可能在前一个间歇调用结束之前调用。

 //间歇调用
var
num=0, max=5, intervalId=null; function incrementNumber(){ num++; if(num==max){ clearInterval(intervalId); //当num=max时取消间歇调用 alert(num); } } setInterval(incrementNumber,1000); //间歇调用

    //用超时调用模拟间歇调用
    var num=0,
    max=5;
    function incrementNumber(){
       num++;
       if(num<max){
          setTimeout(arguments.callee,1000); //回调函数,且解除函数与函数名的耦合关系
       }else{
          alert(num);
       }
    }
   setTimeout(incrementNumber,1000); //超时调用

 

3.超时调用的代码都是在全局作用域中执行的因此函数的this值在非严格模式下指向window对象,在严格模式下是undefined。

var name="liu";
   var o={
       name:"liuliu",
       sayName:function(){
           alert(this.name);   //liuliu
       }
   };
   o.sayName();

//超时调用的this值
 var name="liu";
   var o={
       name:"liuliu",
       sayName:function(){
           setTimeout(function(){   //超时调用
               alert(this.name);    //liu
           },1000);
       }
   };
   o.sayName();

4.调用的两种方式:

      function sayName(){
          alert("liu");
       }
       function test(){
           function sayName(){
              alert("liuliu");
           }

           setTimeout(sayName,1000);   //liuliu
           setTimeout("sayName()",1000);  //liu
      }
      test();

////////////////////////////////////////////////////
function sayName(){ alert("liu"); } function test(){ /* function sayName(){ alert("liuliu"); }*/ setTimeout(sayName,1000); //liu setTimeout("sayName()",1000); //liu } test(); //////////////////////////////////////////////////// /* function sayName(){ alert("liu"); }*/ function test(){ function sayName(){ alert("liuliu"); } setTimeout(sayName,1000); //liu setTimeout("sayName()",1000); //显示sayName未定义 } test(); //////////////////////////////////////////////////// (function(){ //添加了个块级作用域 function sayName(){ alert("liu"); } function test(){ function sayName(){ alert("liuliu"); } setTimeout(sayName,1000); //liuliu setTimeout("sayName()",1000); //显示sayName未定义 } test(); })();

setTimeout("sayName()",1000)这种形式,只能调用全局作用域中的函数,我不建议使用这种方式。setTimeout(sayName,1000)遵守一般的作用域访问规则。
原文地址:https://www.cnblogs.com/webliu/p/4431331.html