<!DOCTYPE html> <head> <title>setTimeout</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> </head> <body> <script> var name = '!!'; var obj = { name:'monkey', print:function(){ console.log(this.name); }, test:function(){ //this.print setTimeout(this.print,1000); } } obj.test(); </script> </body> </html>
通过chrome调试器,查看输出结果:
咦,它怎么输出的是”!!”呢?不应该是obj里的”monkey”吗?!!
这是因为setTimeout中所执行函数中的this,永远指向window。
不对吧,那上面代码中的setTimeout(this.print,1000)里的this.print怎么指向的是obj呢?!!
注意哦,我这里说的是“延迟执行函数中的this”,而不是setTimeout调用环境下的this。
什么意思?
setTimeout(this.print,1000),这里的this.print中的this就是调用环境下的;
而this.print=function(){console.log(this.name);},这个匿名函数就是setTimeout延迟执行函数,其中的this.name也就是延迟执行函数中的this啦。
嘿嘿,这下明白了吧。
var age = 24; function Fn(){ this.age = 18; setTimeout(function(){ //this代表window console.log(this); //输出24,而不是Fn的18 console.log(this.age); },1000); } new Fn();
咦,那有个疑问,比如我想在setTimeout延迟执行函数中的this指向调用的函数呢,而不是window?!!我们该怎么办呢。
常用的方法就是利用that。
that?
对,that。利用闭包的知识,让that保证你传进去的this,是你想要的。
详情见下:
var age = 24; function Fn(){ //that在此 var that = this; this.age = 18; setTimeout(function(){ console.log(that); console.log(that.age); },1000); } new Fn();
还有一种方法就是,利用bind。
如下:
var age = 24; function Fn(){ this.age = 18; //bind传入this setTimeout(function(){ console.log(this); console.log(this.age); }.bind(this),1000); } new Fn();