前端JS: this指向

6 阅读2分钟

核心规则

this指向当前调用函数的那个对象(谁调用,this就指向谁)。


常见场景

1. 普通函数调用

函数独立调用时,this默认指向 全局对象(浏览器中是 window,Node.js 中是 global)。

function show() {
  console.log(this); // 浏览器中输出:window
}
show();

严格模式下,thisundefined

2. 对象方法调用

函数作为对象的方法被调用时,this指向 调用该方法的对象

const user = {
  name: '小明',
  sayHi() {
    console.log(this.name); // 输出:小明
  }
};
user.sayHi();

3. 构造函数调用

通过 new调用构造函数时,this指向 新创建的实例对象

function Person(name) {
  this.name = name; // this 指向新实例
}
const p = new Person('小红');

4. 箭头函数

箭头函数没有自己的 this,它的 this继承自定义时所在的外部作用域

const obj = {
  name: '小李',
  say: () => {
    console.log(this.name); // 输出 undefined(这里 this 指向外层,可能是 window)
  }
};
obj.say();

5. 事件处理函数

在 DOM 事件中,this通常指向 触发事件的元素

button.addEventListener('click', function() {
  console.log(this); // 输出:<button>元素
});

6. 通过 call / apply / bind 显式绑定

可以手动指定 this的指向。 通过 call, apply, bind 方法,可以强制指定函数执行时的 this 值。

call 和 apply:立即调用函数,并指定 this 和参数。

bind:不会立即调用函数,而是返回一个绑定了指定 this 值的新函数。

function introduce(lang1, lang2) {
  console.log(`My name is ${this.name} and I know ${lang1} and ${lang2}`);
}
 
const student = { name: 'Bob' };
 
// 使用 call
introduce.call(student, 'JavaScript', 'Python');
// 输出: "My name is Bob and I know JavaScript and Python"
 
// 使用 apply
introduce.apply(student, ['Java', 'C++']);
// 输出: "My name is Bob and I know Java and C++"

// 使用 bind
const boundIntroduce = introduce.bind(student, 'Go');
boundIntroduce('Rust'); // 输出: "My name is Bob and I know Go and Rust"
// 非常适合用在回调函数中,防止 this 丢失


一句话总结

  • 普通函数:看调用方式,默认 window(严格模式 undefined)。
  • 对象方法:指向调用它的对象。
  • 构造函数:指向新实例。
  • 箭头函数:指向定义时的外层 this不受调用方式影响
  • call/apply/bind:可手动改变 this指向。