你不知道的JavaScript——this词法

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。

猜你喜欢

转载自www.cnblogs.com/em2464/p/10373708.html