函数中this指向的问题,理解这一篇就可以啦!!!

804 阅读2分钟

很多人遇到函数中this指向的问题会分辨不清,因此写下这篇文章,方便记忆理解。

普通函数中的this问题:

结论:this 永远指向 调用函数对象

直接通过代码进行分析,举例如下:

1function test(){
    var a = 1;
    console.log(this.a);
}

test(); //undefined

例1代码执行了test方法,结果并没有打印出方法内定义的局部变量a,而是打印了undefined。因为此时test是window对象的方法,里面的this指向了window。

例2:
var b = 2; //window对象下的变量

function test(){
   var b = 1;
   console.log(this.b);
}

test(); // 打印结果为 2

例2在window下声明了变量b,因此最后打印出了2。

下面是一个更加复杂的例子:

3var name = 'China';
var obj = {
    name : 'America',
    show : function() {
        console.log(this.name)
    }
}

obj.show(); // America

上面的的例3中,obj的show方法执行后打印出America,很显然show方法里面的this指向了obj对象(也就是show方法的调用对象)。

4:
var name = 'China';
var obj = {
    name : 'America',
    show : function() {
        return function(){
            console.log(this.name);
        }
    }
}

var a = obj.show();
a(); // China

上面的例4中show方法执行后,返回了一个匿名函数,a方法定义在window下,因此里面的this指向window,打印出window下的变量name。

箭头函数中的this问题:

箭头函数是函数的简洁写法,但是它的this问题和普通函数还是有所不同。

结论:箭头函数的this指向它所在作用域里面的对象。

5var name = 'window_name'; 

var A = {
   name: 'A',
   sayHello: () => {
      console.log(this.name)
   }
}

A.sayHello();//window_name

上面的例5中出现了箭头函数,最后的打印结果是window_name,因为A是声明在window下,箭头函数所在的作用域下的对象是window,因此输出window下声明的name变量。

那么如何使得this指向对象A呢?可以使用以下的方式:

6:
var name = 'window_name'; 
var A = {
   name: 'A_name',
   sayHello: function(){
      var s = () => console.log(this.name)
      return s//返回箭头函数
   }
}
var sayHello = A.sayHello();
sayHello();// 输出A_name
var B = {
   name: 'B_name';
}
sayHello.call(B); //还是A_name
sayHello.call(); //还是A_name

箭头函数的this,在定义完成的时候就确定了。箭头函数所在的作用域是sayHello函数内的作用域,里面的this指向A,因此后面即使有改变this指向的call,仍然不会影响最后的结果。

例8:
var name = "zhansan";
function Person() {
    //this指向实例one
    var s = () => {
        console.log(this.name); //lisi
    }
    this.fn = s;
}
const one = new Person();
one.name = "lisi";
one.fn();

上面的例8可以辅助理解上面的结论。