this指向判断

307 阅读2分钟

场景1:函数直接调用

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

函数直接调用this指向window

场景2:函数被别人调用

function myfunc() { 
  console.log(this)
};
var a = {
  age: 10,
  myfunc: myfunc 
};
a.myfunc();

this指向调用函数的那个对象a

场景3:new⼀个实例时

function Person(name) { 
  this.name = name; 
  console.log(this);
}
var p = new Person('zhangsan');

this指向new出的对象实例p

场景4: apply、call、bind时

function getColor(color) { 
  this.color = color;
  console.log(this);
}
function Car(name, color) {
  this.name = name;
  getColor.call(this, color); 
  // call会将getColor中的this变为call的第一个参数
  // 本处是Car的实例car,所以当前调用下getColor中的  this指向car
}
var car = new Car('卡⻋', '绿⾊'); // 这个时候Car中的this指向了car

场景5:箭头函数中的this

setTimeout中的this

var a = {
  age:10myfunc: function() {
    setTimeout(function() { 
      console.log(this); 
     }, 0)
    } 
  };
  a.myfunc();

setTimeout()是window.setTimeout()的简写,其中的this指向的是window。

如果我们想让setTimeout中的this能指向a对象,我们可以

var a = {
  age:10let this = that // 这里先存一下指向a对象的this为that
  myfunc: function() {
    setTimeout(function() { 
      console.log(that.age); 
     }, 0)
    } 
  };
  a.myfunc();

还可以通过箭头函数的形式使得this的指向靠着箭头函数最近的外层非箭头函数指向的this,这里就是myfunc指向的this。

  var a = {
    age:10,
    myfunc: function() {
      setTimeout(()=> {
        console.log(this.age);
      }, 0)
    }
  };
  a.myfunc();

总结

1、对于直接调⽤的函数来说,不管函数被放在了什么地⽅,this都是window

2、对于被别⼈调⽤的函数来说,被谁点出来的,this就是谁

3、在构造函数中,类中(函数体中)出现的this.xxx=xxx中的this是当前类的⼀个实例

4、call、apply时,this是第⼀个参数。bind要优与call/apply哦,call参数多,apply参数少 (tip:有时候我们会混淆到底是call参数多还是apply,可以把call理解成打电话,电话要一个一个打,所以参数要一个一个传,参数就多。)

5、箭头函数没有⾃⼰的this,需要看其外层的是否有函数,如果有,外层函数的this就是内部箭头函数 的this,如果没有,则this是window。

6、普通函数和箭头函数的this判断时机不同,普通函数的this是函数调用的时候判断,箭头函数是函数定义时判断,也就是通过箭头函数定义的词法作用域判断。

7、通常把根据调用关系进行的绑定称为隐式绑定,把通过call、apply、bind、new对this的绑定称为显式绑定,显示绑定的优先级高于隐式绑定,new的优先级比bind显示绑定要高,箭头函数优先级最高。 所以优先级从低到高以此为(隐式 < 显式(bind) < 显示(new)< 箭头函数))。