JavaScript 词条目录
前端Wiki/JavaScript/深入/原型与 this

this 指向

this 是很多初学者的噩梦,其实规则只有一句话:this 由函数的调用方式决定,而不是定义位置。常见情况按优先级排列:

  • obj.fn() 方法调用:this 指向点号前面的 obj;
  • fn() 独立调用:非严格模式指向 window,严格模式是 undefined;
  • new Fn() 构造调用:this 指向新创建的实例;
  • fn.call/apply/bind(obj):显式指定 this,call/apply 立即调用(区别在传参形式),bind 返回绑定好的新函数;
  • 箭头函数:没有自己的 this,沿用定义时外层的 this,且无法被 call/bind 改变。

回调场景里 this 丢失是高频 bug:把对象的方法作为回调传出去后,this 就不再是原对象。解决办法是改用箭头函数或 bind。

本节要点this 看调用方式:方法调用指向宿主对象,独立调用指向 window/undefined;call/apply/bind 可显式指定;箭头函数沿用外层 this。
JavaScript
const user = {
  name: '小明',
  normal() {
    console.log('方法调用 → this 是:', this.name); // user
  },
  arrow: () => {
    // 箭头函数沿用外层(此处是模块/全局)的 this,不是 user
    console.log('箭头函数 → this 不是 user');
  },
};
user.normal();
user.arrow();

// 独立调用:this 指向 window(非严格模式)
function loose() {
  console.log('独立调用 → this:', this === window);
}
loose();

// call / bind:显式指定 this
function intro(city) {
  console.log(this.name + ' 来自 ' + city);
}
intro.call({ name: '小红' }, '上海');    // 立即调用
const bound = intro.bind({ name: '小刚' }); // 返回新函数
bound('北京');

// 经典坑:setTimeout 回调丢失 this
const timer = {
  seconds: 0,
  start() {
    // 普通函数里 this 不是 timer;箭头函数才能保住
    setInterval(() => this.seconds++, 1000);
  },
};