https://www.cnblogs.com/hutaoer/p/3423782.html
https://www.cnblogs.com/vicky-li/p/8669549.html
https://www.cnblogs.com/sspeng/p/6633204.html
https://www.jb51.net/article/112334.htm
https://www.cnblogs.com/heshan1992/p/6667596.html
var obj={ id:"awesome", cool:function coolFn(){ console.log(this.id); } }; var id="not awesome"; obj.cool(); //awesome setTimeout(obj.cool,100); //not awesome
setTimeout方法是挂在window对象下的。《JavaScript高级程序设计》:超时调用的代码都是在全局作用域中执行的,因此函数中this的值在非严格模式下指向window对象,在严格模式下是undefined。
setTimeoutff中所执行函数中的this,永远指向window!注意是要延迟执行的函数中的this。
setTimeout调用环境中的this的指向是需要根据上下文来确定的,默认为window,延迟执行函数中的this就是指向window。
上面代码问题在于setTimeout中的cool()函数丢失了同this之间的绑定。解决这个问题有好几种办法,但最常见的就是var self=this; 如下:
var obj={ count:0, cool:function(){ var self=this; if(self.count<1){ setTimeout(function timer(){ self.count++; console.log("awesome?"); },100); } } } obj.cool();//awesome?
ES6中的箭头函数引入了一个叫作this词法的行为:
var obj={ count:0, cool:function coolFn(){ if(this.count<1){ setTimeout( ()=>{ this.count++; console.log("awesome?"); },100) } } }; obj.cool(); //awesome?
箭头函数在涉及this绑定时的行为和普通函数的行为完全不一致。它放弃了所有普通this绑定的规则,取而代之的是用当前的词法作用域覆盖了this本来的值。
var obj={ count:0, cool:function(){ if(this.count<1){ setTimeout(function(){ this.count++; console.log('more awesome'); }.bind(this),100); } } } obj.cool();
函数调用的方式有4种,this也有4种指向:
1.独立调用:func(),函数独立调用,this指向window
2.方法调用:obj.func(),函数作为obj的一个方法(属性)调用,this指向obj.
3.构造函数调用:new Func(),如果在一个函数前面带上new关键字来调用,那么背地里将会创建一个连接到该函数的prototype的新对象,this指向这个新的对象。
4.call、apply、bind调用:func.call(obj,value1,valu2); func.apply(obj,[value1,value2]); func.bind(obj,value1,value2)(); fun.bind(obj)(value1,value2); 动态改变this的指向obj。