setTimeout和setInterval中使用this

JavaScript代码闭包

  1. var roll = function(objid, step, direct)  

其中objid为要滚动的容器ID,step为每一轮滚动的距离,direct为滚动方向。基础结构和一些方法就不去管了,直接进入关键点。this

roll类的主要方法(都经过prototype设置)有:spa

initroll(); //初始化滚动
playroll(); //开始滚动
stoproll(); //中止滚动
rollPlaying(); //滚动处理
rollReset(); //重置滚动内容prototype

能够看出,个人设想是,建立滚动版只须要:code

JavaScript代码
  1. var imgroll = new roll('rollImages', 120, 'TOP');   
  2. imgroll.initroll();  

这里已经在建立实例的时候初始化了,为何还要initroll呢?由于我想,滚动动做并非加载后当即执行的,而是在设定的几秒时间后,因此在initroll()中的最重要的内容即是:ip

JavaScript代码
  1. roll.prototype.initroll = function(){   
  2.     this.objtimeout = setTimeout(this.playroll, this.iResume);   
  3. }  

有经验的人可能看出了这里的问题,但是我却一点都没有发觉,这里记录一下问题一作用域

playroll(),stoproll()都只是开关来控制rollPlaying(),他们的内容分别是:it

JavaScript代码
  1. roll.prototype.playroll = function(){   
  2.     this.objrolling = setInterval(this.rollPlaying, this.iTime);   
  3. }  
JavaScript代码
  1. roll.prototype.stoproll = function(){   
  2.      clearTimeout(this.objtimeout);   
  3.      clearInterval(this.objrolling);   
  4. }  

这里playroll()出了和上面同样的问题记录问题二io

rollPlaying()中的滚动处理自己并无什么问题,可是由于上面出现的错误而致使了运行出错。那么问题在哪里呢?function

问题一:setTimeout(func, time)里面的func我使用了this关键字,来标识是类实例的方法,至少我我的一直认为是这样的,func参数中使用this关键字自己并无问题, 能够正确在time时间后执行playroll(),但是在playroll()里面就碰到了问题二。(可能有人会说,你的setTimeout的func参数没有带括号,实事证实有括号的状况比没有更惨烈。。。)

问题二:可见我在playroll()中使用了大量的this关键字来标识roll类实例的元素或方法,可是由于问题一是在setTimeout中使用playroll()这个方法,所以这里的this已经不是我设想的类实例的this关键字了。我至今尚未弄明白在前面的setTimeout中使用this关键字的方法致使了playroll中的this变成了什么,总而言之这个this已经不是roll的一个实例了。前面也说playroll()中的错误和initroll()中的错误同样,一样致使了rollPlaying()中的this关键字失效。

解决问题的方法应该有两个:其一是不使用this关键字而用其余的方式替代(由于我以为太麻烦并且会破坏结构因而放弃了);其二是我如今用的解决方案,以下:

JavaScript代码
  1. roll.prototype.initroll = function(){   
  2.     var o = this;   
  3.     this.objtimeout = setTimeout(function(){o.playroll(o)}, this.iResume);   
  4. }  
JavaScript代码
  1. roll.prototype.playroll = function(o){   
  2.     this.objrolling = setInterval(function(){o.rollPlaying();}, this.iTime);   
  3. }  

我在initroll()中建立了一个变量o为this自己,再使用匿名方法把o做为实例自己,也做为参数传递给了playroll(),为何要既做为实例自己又做为参数呢?做为实例的做用是能够在playroll()中使用this关键字,而做为参数是为了在playroll()当中不用再为setInterval从新申明一个实例。

有人可能会说,为何不setTimeout(function(){this.playroll()}, this.iResume)呢?这样显然不行的缘由连试都不用试了,由于这样的状况下匿名方法内的this关键字变成了匿名方法自己而不是外部类,因此才须要一个变量来处理,或者能够看做一个闭包,在initroll结束以后o变量的做用域仍然存在。

为了这个问题绕了一些弯路,以为应该记录一下,以备后患。

相关文章
相关标签/搜索