您的位置:首页 > 职场人生

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

2017-06-11 16:14 597 查看
有一道简单的面试题也不怕大家笑话,先上题。

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数 面试题