setTimeout和setInterval的一些区别(浏览器之间参数的差别,函数本身的一些差别)(1)

1.本身的一些差别:

 

这两个方法都可以用来实现在一个固定时间段之后去执行JavaScript。不过两者各有各的应用场景。

方 法
实际上,setTimeout和setInterval的语法相同。它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码。

不过这两个函数还是有区别的,setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。

虽然表面上看来setTimeout只能应用在on-off方式的动作上,不过可以通过创建一个函数循环重复调用setTimeout,以实现重复的操作:

File: settimeout_setinterval.js

showTime();

function showTime()

{

    var today = new Date();

    alert("The time is: " + today.toString());

    setTimeout("showTime()", 5000);

}

一旦调用了这个函数,那么就会每隔5秒钟就显示一次时间。如果使用setInterval,则相应的代码如下所示:

File: settimeout_setinterval2.js

setInterval("showTime()", 5000);

function showTime()

{

    var today = new Date();

    alert("The time is: " + today.toString());

}

这两种方法可能看起来非常像,而且显示的结果也会很相似,不过两者的最大区别就是,setTimeout方法不会每隔5秒钟就执行一次 showTime函数,它是在每次调用setTimeout后过5秒钟再去执行showTime函数。这意味着如果showTime函数的主体部分需要2 秒钟执行完,那么整个函数则要每7秒钟才执行一次。而setInterval却没有被自己所调用的函数所束缚,它只是简单地每隔一定时间就重复执行一次那 个函数。

如果要求在每隔一个固定的时间间隔后就精确地执行某动作,那么最好使用setInterval,而如果不想由于连续调用产生互相干扰的问题,尤其是每次函数的调用需要繁重的计算以及很长的处理时间,那么最好使用setTimeout。

 

 

 

2. 浏览器之间的差别:

 

setTimeout与setInterval是window对象的两个非常神奇方法,用于实现定时或延时调用一个函数或一段代码。
(新手可能认为setTimeout与setInterval是javascript函数,这是错误的。新手容易将javascript对象函数与DOM对象方法混淆。)

先来一段代码,大家猜猜在各种浏览器下的结果会是怎么样的呢?

JScript code
function f(){
   var  s  = ' arguments.length: '   + arguments.length + ' ; ' ;
   for ( var  i = 0 ,n = arguments.length;i < n;i ++ ){
       s += ' [ ' + i + ' ]: ' + arguments[i] + ' ; ' ;
   }
   alert(s);
}
setTimeout(f, 500 , " javascript " , " AAA " );


我这里要探讨的,不是什么时候该用哪一个,而是探讨这两个方法在各浏览器中的差异。

原先我一直没觉得这两个方法会有什么乌龙,一个偶然的机会让我得知了,现在整理一下写出来和大家分享。

因为setTimeout与setInterval的参数和用法是一样的,只是功能不同,所以,为了省事,我下面只以setTimeout为例进行说明以及举例。

setTimeout被最经常用到的形式大概是如下2种样子的:

JScript code iTimerID = setTimeout(strJsCode, 50 ) // strJsCode为一个包含 js代码的字符串 iTimerID = setTimeout(objFunction, 50 ) // objFunction为一个函数对象



第一种调用方式是传包含js代码的字符串,这种方式的好处是简洁,但坏处是运行效率差,而且不利于语法解析,有潜在风险,更重要的是,处理比较复杂的内容比较费劲,这一点和eval的弊端是一致的。
所以,我们认为,通常应当采用第二种方式调用为好。(后面我的例子均采用第2种调用方式)


现在来揭晓开头那一段代码在各种浏览器下的结果:
IE(6,7,8)是: arguments.length:0;
Opera(6,7,8)是: arguments.length:2; [0]:javascript; [1]:AAA;
Firefox(3.0)是: arguments.length:3; [0]:javascript; [1]:AAA; [2]:-15;

竟然有这么大的差别,还真是“你唱你的曲,我哼我的调”!
Firefox(3.0)下,得出的最后一个数字是不特定的,有时候是0,有时候是一个负数,这问题后面再说。


(一)IE系列中的setTimeout

首先,我们看看微软出的DHTML参考手册中是如何说的:

setTimeout Method
  Evaluates an expression after a specified number of milliseconds has elapsed.

Syntax
  iTimerID = window.setTimeout(vCode, iMilliSeconds [, sLanguage])

Parameters
  vCode Required. Variant that specifies the function pointer or string that indicates
  the code to be executed when the specified interval has elapsed.
  iMilliSeconds Required. Integer that specifies the number of milliseconds.
  sLanguage Optional. String that specifies one of the following values:
  JScript Language is JScript.
  VBScript Language is VBScript.
  JavaScript Language is JavaScript.

MSDN上关于setTimeout的说明:
  http://msdn.microsoft.com/en-us/library/ms536753(VS.85).aspx

也就是说,setTimeout接收3个参数,第3个参数表示脚本语言的类型,如果你再传入更多的参数,是无意义的。
因此,在IE中,以下两种都是对的。

JScript code setTimeout( ' alert(1) ' , 50 ); setTimeout( ' msgbox "终止、重试、忽略,您看着办吧。", vbAbortRetryIgnore +vbDefaultButton2, "告诉您" ' , 50 , ' VBScript ' );
   
   



(二)Mozilla系列中的setTimeout

我们看看Mozilla官方网站上 Gecko DOM Reference 手册中是如何说的:
window.setTimeout
  Summary
  Executes a code snippet or a function after specified delay.

  Syntax
  var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
  var timeoutID = window.setTimeout(code, delay);

前两个参数都一样,没差别,从第三个参数就不同了。
因为目前只有IE浏览器支持多种语言的脚本,其它浏览器只支持js脚本所以不需要传语言类型的参数。
Mozilla把传给setTimeout的第3个以及更后面的更多参数依次的传给前面的func做为参数。
Firefox, Opera, Safari, Chrome等等也都是如此。

但是注意到,Mozilla上说了他家的setTimeout有一个叫做"Lateness" argument的BUG.
  "Lateness" argument
  Functions invoked by setTimeout are passed an extra "lateness" argument in Mozilla,
  i.e., the lateness of the timeout in milliseconds. (See bug 10637 and bug 394769.)
这就是开头那个例子中,Firefox(3.0)下有一个乌龙数字的根源。

Mozilla上关于setTimeout的说明:
  https://developer.mozilla.org/en/DOM/window.setTimeout

(三)其它浏览器系列(Opera, Safari, Chrome)中的setTimeout
  和Mozilla系列中的基本一样,但是没有Mozilla系列中的多一个参数的BUG.


武林外传:使用setTimeout的小技巧


  (1)IE中给setTimeout中的调用函数传参数
  上面的分析可知,IE是不支持在setTimeout中给被调用的函数传参数的,为了浏览器世界的和谐,我们可以把函数调用参数包裹进新的匿名函数中。示例:
  function f(a){
  alert(a);
  }
  // setTimeout(f,50,'hello'); //用于非IE
  setTimeout(function(){f('hello')},50); //通用
  var str='hello';
  setTimeout(function(){f(str)},50); //通用

  (2)this问题
  setTimeout调用的函数被执行时的上下文是全局,而不再是调用setTimeout方法时的上下文。所以,setTimeout的第一个参数的函 数被执行时其this是指向window的,如果需要保留调用setTimeout方法时的this,就需要把当时的this传进去。示例:
  function Person(name){
  this.name=name;
  var f=function(){alert('My name is '+this.name)};

  // setTimeout(f,50); //错误

  var THIS=this;
  setTimeout(function(){f.apply(THIS)},50); //正确,通用
  setTimeout(function(){f.call(THIS)},50); //正确,通用
  }
  new Person('Jack');

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值