前端学习/踩坑系列1:常见需要改变this指向的问题

141 阅读2分钟

常见一些需求比如在setTimeout()中使用this关键字,或者jQuery的ajax请求亦或微信小程序中网络请求函数中,在success、fail函数中使用this关键字,而this的指向并不如自己料想一样。

a. 例如setTimeOut:

var num = 1;
function Obj (){
    this.num = 2,
    this.getNum01 = function(){
        setTimeout(function(){
            console.log(this.num);
        }, 1000)
    };
    var that = this;    //将this存为一个变量,此时的this指向obj
    this.getNum02 = function(){
        setTimeout(function(){
            console.log(that.num);
        }, 1000)
    };
    this.getNum03 = function(){ // 使用bind绑定this指向
        setTimeout(function(){
            console.log(this.num);
        }.bind(this), 1000)
    };
    this.getNum04 = function(){ // 使用箭头函数
        setTimeout(()=>{
            console.log(this.num);
        }, 1000)
    }
}
var obj = new Obj; 
obj.getNum01(); //1或undefined     打印的是window.num
obj.getNum02(); //2     		打印的是obj.num,值为2
obj.getNum03()  //2  	打印的是obj.num,值为2
obj.getNum04()  //2 	 打印的是obj.num,值为2

由于setTimeout()调用的代码运行在与所在函数完全分离的执行环境上,会导致这些代码中包含的 this关键字会指向 window (或全局)对象。可使用以下方法改变this指定问题:

1)将当前对象的引用放在一个变量里使用。

2)bind会显式绑定指定的this。

3)ES6中,箭头函数完全修复了this的指向,this总是指向词法作用域,即外层调用者obj。

b.例如jQuery中的ajax请求:

let that = this;
$.ajax({
    // 其他参数配置省略
    success: (result) => { // 使用箭头函数
        console.log('this=>',this);
    },
    /*
     success: (result) => { // 将this存为一个变量
        console.log('this=>',that);
    },
    */
    error: function(e){
        console.log('this=>',this);
        console.log(e);
    }
});

success使用箭头函数或that=this,this(that)指向上一级调用函数对象,error中使用普通函数,其中的this指向的使用该请求函数本身。因此可以使用箭头箭头函数或者变量存储this获得上一级的this对象。

小声说话:尺之木必有节目,寸之玉必有瑕讁。——战国末期商人,政治家 吕不韦 《吕氏春秋·离俗览·举难》望诸君多多指教。