为了账号安全,请及时绑定邮箱和手机立即绑定

关于setTimeout的问题

关于setTimeout的问题

神不在的星期二 2019-03-20 18:15:09
具体问题就是setTimeout里面执行方法本身的时候,直接写方法名会报错,也许是我搜索的方式不对,没有搜到相关答案。this.timer = setTimeout(self.change, this.s); 这样写会报错写这个是为了实现字体不停变色。function ChangeColor(id,arr,s) {    this.id = id;    this.arr = arr;    this.s = s;    this.i = 0;    this.timer = null;}ChangeColor.prototype = {    change : function () {        let self = this;        if (this.arr[this.i]) {            $(this.id).css('color', this.arr[this.i]);        }        this.i === 0 ? this.i++ : this.i = 0;        // this.timer = setTimeout(self.change, this.s);        this.timer = setTimeout(function () {            // console.log(self);            self.change();        }, this.s);    }};let txt = new ChangeColor('.txt',['#fff','#000'],200);txt.change();
查看完整描述

5 回答

?
狐的传说

TA贡献1804条经验 获得超3个赞

//修改

this.timer = setTimeout(this.change.bind(this), this.s);

初始化运行正常,定时器触发后,change函数作为setTimeout的回调函数,此时this指向了window,执行this.arr[this.i]报错.


最后,函数调用是txt.change(),不是txt.changeColor()


查看完整回答
反对 回复 2019-04-08
?
POPMUISE

TA贡献1765条经验 获得超5个赞

你这不是递归了吗。
递归的话没有边界,跑一会内存会蹦。
在change 函数外面用定时器调用

查看完整回答
反对 回复 2019-04-08
?
ibeautiful

TA贡献1993条经验 获得超5个赞

楼上说的是对的,这是关于this的指向的问题,要搞清楚this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件,this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。具体可以看下我总结的一篇读书笔记JavaScript基础系列--打败this

第一次直接调用txt.change()的时候,this指向txt这个对象,所以self也指向txt这个对象,所以初始化的时候运行正常。
setTimeout的回调的调用位置始终是全局作用域,所以回调里面的this是指向全局对象---浏览器里是window对象,现在你把self.change作为setTimeout的回调,那么定时器到点触发后,回调self.change里的this就指向window了,而window是没有arr,i这些属性的,所以执行到if (this.arr[this.i])时会报错:Cannot read property 'undefined' of undefined


查看完整回答
反对 回复 2019-04-08
?
动漫人物

TA贡献1815条经验 获得超10个赞

如果仅仅是需要达到这个效果,不一定用你的方法,你可以采用循环定时器触发。
然后在相应处理中去操作具体的对象属性值,达到效果。

查看完整回答
反对 回复 2019-04-08
?
芜湖不芜

TA贡献1796条经验 获得超7个赞

楼上说的是对的,这是关于this的指向的问题,要搞清楚this是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件,this的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。具体可以看下我总结的一篇读书笔记JavaScript基础系列--打败this


txt.change()

第一次直接调用的时候,this指向txt这个对象,所以self也指向txt这个对象,所以初始化的时候运行正常。

setTimeout的回调的调用位置始终是全局作用域,所以回调里面的this是指向全局对象---浏览器里是window对象,现在你把self.change作为setTimeout的回调,那么定时器到点触发后,回调self.change里的this就指向window了,而window是没有arr,i这些属性的,所以执行到if (this.arr[this.i])时会报错:Cannot read property 'undefined' of undefined


查看完整回答
反对 回复 2019-04-08
  • 5 回答
  • 0 关注
  • 648 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信