javascript - 为什么这里settimeout只执行了一次
巴扎黑
巴扎黑 2017-04-10 16:37:09
[JavaScript讨论组]
   function aa(){
    }
    aa.prototype.init=function(){
            setTimeout(this.init,1000);
            console.log(1);
        }
    new aa().init();
    
    为什么这里的console.log(1)只有执行了一次?
巴扎黑
巴扎黑

全部回复(4)
天蓬老师

你上面的代码和如下代码相同的

function aa(){
}
aa.prototype.init=function(){
        var tmp=this.init;
        console.log(tmp);
        setTimeout(tmp,1000);
        console.log(1);
    }
var newaa=new aa();
newaa.init();

newaa.init();init方法执行时,将newaa的init方法赋值给tmp,那么此时tmp指向的时init指向的函数对象本身,和newaa对象没有关系了。setTimeout接收一个函数对象或一个字符串表示的代码作为其第1个参数,
接下来设置了一个定时器setTimeout(tmp,1000);,在1000毫秒后执行tmp函数。tmp函数为

function(){
    var tmp=this.init;
    setTimeout(tmp,1000);
    console.log(1);
}

最后执行console.log(1);
输出1
定时器某个时刻触发后执行tmp函数对象,那么此时this为global对象,global对象是没有init方法的,也就是此时tmp的undefined,setTimeout(undefined,1000); setTimeout对一个undefined对象设置定时器是没有任何效果的,且不会报错的!
最后执行console.log(1);
输出1
因为没有新的定时器被设置,所以不会再有输出

解决这个问题方法
A

function aa(){
}
aa.prototype.init=function(){
        var that=this;
        setTimeout(function(){
            that.init();
        },1000);
        console.log(1);
    }
var newaa=new aa();
newaa.init();

B
或bind,可能会有兼容性问题
Chrome7 /Firefox 4/IE 9/Opera 11/Safari 5 都是OK的

function aa(){
}
aa.prototype.init=function(){
        setTimeout(this.init.bind(this),1000);
        console.log(1);
    }
var newaa=new aa();
newaa.init();
ringa_lee

第一次和第二次的this不同。第二次的this 是undefined。

巴扎黑
this指向错误了!!在定时器里的this都是指向window,window是没有init方法,修正下指向
function aa(){
        }
        aa.prototype.init=function(){
            var _this=this;
                setTimeout(function(){
                    _this.init();
                },1000);
                console.log(2);
            }
        new aa().init();
ringa_lee

输出是1,1 这两个,console执行了两次,第一眼看着有点无限循环的意思,不过不是这样的。实际上,一共执行了两次init函数,不过第二次的时候this指向出了问题,不过有点小问题this.init在那个地方,到底是个什么?

function aa(){
 }
 aa.prototype.init=function(){
            setTimeout(function(){console.log(this.init);},1000);
            console.log(1);
        }
    new aa().init();
    
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号