Skip to content

关于 this 的指向一直是一个迷,这里摘至 这里

默认绑定

  • 默认绑定一般发生在回调函数,函数直接调用;
javascript
function test() {
  // 严格模式下是 undefined
  // 非严格模式下是 window
  console.log(this);
}

//setTimeout的比较特殊
setTimeout(function () {
  //严格模式和非严格模式下都是window
  console.log(this);
});

arr.forEach(function () {
  //严格模式下是undefined
  //非严格模式下是window
  console.log(this);
});

隐式调用

  • 这个通俗点用一句话概括就是谁调用就是指向谁
javascript
const obj = {
  name: 'joy',
  getName() {
    console.log(this); //obj
    console.log(this.name); //joy
  }
};
obj.getName();

显示绑定 call,apply,bind

javascript
const obj1 = {
  name: 'joy',
  getName() {
    console.log(this);
    console.log(this.name);
  }
};

const obj2 = {
  name: 'sam'
};

obj1.getName.call(obj2); //obj2 sam
obj1.getName.apply(obj2); //obj2 sam
const fn = obj1.getName.bind(obj2);
fn(); //obj2 sam

new 绑定

javascript
function Vehicle() {
  this.a = 2;
  console.log(this);
}
new Vehicle(); //this指向Vehicle这个new出来的对象

es6 的箭头函数

  • es6 的箭头函数比较特殊,箭头函数 this 为父作用域的 this,不是调用时的 this.
  • 要知道前四种方式,都是调用时确定,也就是动态的,而箭头函数的 this 指向是静态的,声明的时候就确定了下来.比较符合 js 的词法作用域吧
javascript
window.name = 'win';
const obj = {
  name: 'joy',
  age: 12,
  getName: () => {
    console.log(this); //其父作用域this是window,所以就是window
    console.log(this.name); //win
  },
  getAge: function () {
    //通过obj.getAge调用,这里面this是指向obj
    setTimeout(() => {
      //所以这里this也是指向obj 所以结果是12
      console.log(this.age);
    });
  }
};
obj.getName();
obj.getAge();

5 种 this 绑定的优先级

箭头函数 -> new 绑定 -> 显示绑定 call/bind/apply -> 隐式绑定 -> 默认绑定