由setTimeout()里的this引出的this
example 1:
window.id='windowid'; function M(){ this.id='Mid'; this.f1=function(){console.log(this.id);}; this.f2=function(){ setTimeout(this.f1,5000); }; } var m=new M(); m.f2(); //'windowid'
example 2:
window.id='windowid'; function M(){ this.id='Mid'; this.f1=function(){console.log(this.id);}; this.f2=function(){ setTimeout(function(){this.f1();},5000); }; } var m=new M(); m.f2(); //Error: undefined is not a function
example 3:
window.id='windowid'; function M(){ this.id='Mid'; this.f1=function(){console.log(this.id);}; this.f2=function(){ var that=this; setTimeout(that.f1,5000); }; } var m=new M(); m.f2(); //'windowid'
example 4:
window.id='windowid'; function M(){ this.id='Mid'; this.f1=function(){console.log(this.id);}; this.f2=function(){ var that=this; setTimeout(function(){that.f1();},5000); }; } var m=new M(); m.f2(); //'Mid'
setTimeout(fun,time)中的fun是在全局对象:`window`下执行的。example3和example4的区别在于:
example3相当于在全局下执行:
(function(){console.log(this.id);})(); //this-->global object:window
example4相当于在全局下执行:
(function(){that.f1();})(); //this in side of that.f1--> m.prototype
补充:
this指谁由调用函数的方式决定,如下所示。
function foo() { console.log(this); } //作为普通的函数调用 foo(); // this -->全局对象:`window` //作为一个对象的方法属性调用 var obj = {bar: foo}; obj.bar(); // this --> `obj` // 作为构造函数调用 new foo(); // this --> `foo.prototype`
手动指定this的方式:
1. fun.call(thisobj,param1,param2,...);
2. fun.apply(thisobj,[arguments]);
3. fun.bind(thisobj,param1,param2,...)----return a fun;
example:
this.x='windowX'; var obj={ x:'ojbX', f1:function(a){console.log(this.x+a);} } var fun=obj.f1; fun(1); fun.call(this,1); fun.apply(this,[1]); fun.bind(this,1)(); fun.call(obj,1); fun.apply(obj,[1]); fun.bind(obj,1)(); //windowX1 //windowX1 //windowX1 //windowX1 //ojbX1 //ojbX1 //ojbX1
利用bind修改上例中的setTimeout:
window.id='windowid'; function M(){ this.id='Mid'; this.f1=function(){console.log(this.id);}; this.f2=function(){ setTimeout(this.f1.bind(this),5000); }; } var m=new M(); m.f2(); //'Mid'
再来看看setTimeout里function的参数问题:
var i=9; setTimeout(function(i){console.log(i);},1000) ;
//输出结果是????
for(var i=0;i<10;i++){ setTimeout(function(){console.log(i);},1000) ; } //输出结果是????,输出结果的间隔是??? for(var i=0;i<10;i++){ setTimeout(function(i){console.log(i);},1000) ; } // ?????? for(var i=0;i<10;i++){ ( function(i){ setTimeout(function(){console.log(i);},1000) }) (i); }