由一道面试题引发的setTimeout的用法思考
2017-06-11 16:14
597 查看
有一道简单的面试题也不怕大家笑话,先上题。
问:如何通过调用sayname方法输出‘guguji’?
obviously,是想通过改变函数的作用域来实现的,我告诉面试官B.sayName.call(A)可以,apply亦然,但是面试官问我还有啥方法吗?我没答出(好菜自己)。another answer is the Bind function。
面试官大神说了,回家赶紧一通查bind。里边有这么一段demo很好奇,不加bind会发生什么。
bind去掉,bloom方法改成酱紫。
发现可以正确的打印出信息,咦~不对,是直接打印的,没有延时1s。好好回想一下自己用settimeout的时候,是这么写的。
改成方法名的话
settimeout这个函数默认会把this指向window,JavaScript自己也明白这个缺陷,所以在文档了也列出了解决方法,1、像我常用的的那样,套个function(){ ‘把你想执行的方法放在这里’}。2、使用箭头函数。
section one
酱紫肯定报错啊,window下边肯定没有declare方法,咋办尼肯定得把lateBloomer传进去才对。别忘了settimeout有第三个参数,大抵是这样。
section two
Unexpectedly it works.箭头函数里的this并不是window??the answer is no.阮一峰blog的解释“函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。”一些有关箭头函数的资料,mdn定义,why not use arrow function
。
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
。
相关文章推荐
- 一道面试题引发的有关随机数的思考(4)
- 一道面试题引发的有关随机数的思考(8)
- 2015百度一道面试题引发的思考(shell脚本和网络)
- 腾讯高级工程师:一道面试题引发的高并发性能调试思考
- (转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考
- 一道面试题引发的有关随机数的思考(5)
- 一道360面试题引发的思考
- 一道面试题引发的思考
- 一道面试题引发的思考
- 一道面试题引发的对数据类型转换的思考
- 由一道面试题引发的思考
- JAVA学习提高之---- 一道面试题引发的思考之:类的初始化
- 一道关于静态构造函数与抽象类构造函数的面试题引发的思考
- 2015百度一道面试题引发的思考(shell脚本和网络)
- 一道面试题引发的有关随机数的思考(2)
- 一道面试题引发的有关随机数的思考(7)
- 一道360面试题引发的思考
- [复习] (int&)a 表示什么? 一道面试题引发的思考
- 一道js面试题引发的思考
- (转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考