由一道面试题引发的setTimeout的用法思考

有一道简单的面试题也不怕大家笑话,先上题。

var A={
    name:'guguji'
    };
var B={
    name:'dukuan',
    sayName:function(){
        console.log(this.name)
        }
    }       

问:如何通过调用sayname方法输出‘guguji’?
obviously,是想通过改变函数的作用域来实现的,我告诉面试官B.sayName.call(A)可以,apply亦然,但是面试官问我还有啥方法吗?我没答出(好菜自己)。another answer is the Bind function。
面试官大神说了,回家赶紧一通查bind。里边有这么一段demo很好奇,不加bind会发生什么。

function LateBloomer() {
  this.petalCount = Math.ceil(Math.random() * 12) + 1;
}

// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
  window.setTimeout(this.declare.bind(this), 1000);
};

LateBloomer.prototype.declare = function() {
  console.log('I am a beautiful flower with ' +
    this.petalCount + ' petals!');
};

var flower = new LateBloomer();
flower.bloom();  // 一秒钟后, 调用'declare'方法

bind去掉,bloom方法改成酱紫。

LateBloomer.prototype.bloom = function() {
  window.setTimeout(this.declare(), 1000);
};

发现可以正确的打印出信息,咦~不对,是直接打印的,没有延时1s。好好回想一下自己用settimeout的时候,是这么写的。settimeout(function(){console.log('guguji')},1000),就明白了,这里也摆上settimeout的定义,原来settimeout里边可以传三个以上的参数。第一个是方法,第二个是delay延时,第三个param是方法调用时候传入的参数。通俗点理解就是执行到settimeout的时候,会往调用堆栈里放入一个函数,delay后执行,参数为param。而我上边那样写呢,settimeout传入的第一个不是方法名,而直接调用了一个方法,所以,就直接执行咯。
改成方法名的话settimeout(this.declare,1000)就会在declare执行的时候遇到this指向window的情况,所以必须像文档上写的bind(this)一下。(注:bind的这个括号,只是改变function的this指向,并没有调用)

settimeout这个函数默认会把this指向window,JavaScript自己也明白这个缺陷,所以在文档了也列出了解决方法,1、像我常用的的那样,套个function(){ ‘把你想执行的方法放在这里’}。2、使用箭头函数。


section one

 LateBloomer.prototype.bloom = function() {
      setTimeout(function(){
        this.declare();
      }, 1000);
    };

酱紫肯定报错啊,window下边肯定没有declare方法,咋办尼肯定得把lateBloomer传进去才对。别忘了settimeout有第三个参数,大抵是这样。

 LateBloomer.prototype.bloom = function() {
      setTimeout(function(This){
        This.declare();
      }, 1000,this);
    };

section two

 LateBloomer.prototype.bloom = function() {
      setTimeout(()=>{
        this.declare();
      }, 1000);
    };

Unexpectedly it works.箭头函数里的this并不是window??the answer is no.阮一峰blog的解释“函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。”一些有关箭头函数的资料,mdn定义why not use arrow function

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值