返回

JavaScript 中 Class 的 `this` 指向

前端

引言

在 JavaScript 中理解 this 指向对于编写健壮且可维护的代码至关重要。而在使用 class 创建对象时,this 的行为可能会有些复杂,因此需要特别关注。本文将深入探讨 JavaScript 中 class 中的 this 指向,并提供清晰的解释和示例,以消除常见的困惑。

this 的绑定优先级

理解 this 的绑定优先级对于解析其在 class 中的行为至关重要。JavaScript 中 this 的绑定遵循以下优先级:

  1. 显式绑定: 使用 bind()call()apply() 显式设置 this 的值。
  2. 隐式绑定: 通过调用对象的方法或访问对象的属性隐式设置 this 的值。
  3. 默认绑定:this 无法通过显式或隐式绑定获得时,它将默认绑定到全局对象(在浏览器中为 window)。

class 中的 this 指向

在 class 中,this 始终隐式绑定到 class 的实例。这意味着当实例化一个 class 时,this 将指向该实例。

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}.`);
  }
}

const person = new Person("John");
person.greet(); // Output: Hello, my name is John.

在上面的示例中,当 person 对象实例化后,thisgreet() 方法内部绑定到该对象。这使得 this.name 能够访问 person 对象的 name 属性。

处理方法中的 this 指向

需要注意的是,箭头函数不会绑定自己的 this 值。这意味着如果在 class 的方法中使用箭头函数,this 将指向函数外部的 this,而不是 class 的实例。

class Person {
  constructor(name) {
    this.name = name;
  }

  greet = () => {
    console.log(`Hello, my name is ${this.name}.`);
  };
}

const person = new Person("John");
person.greet(); // Output: Hello, my name is undefined.

在上面的示例中,greet() 方法是一个箭头函数,它不会绑定自己的 this 值。因此,this.name 实际上指向的是全局对象(window),而不是 person 对象。这会导致 greet() 方法输出 undefined

解决方法中的 this 指向

为了确保方法中 this 的正确指向,可以使用以下技术:

  • 使用常规函数: 常规函数会绑定自己的 this 值,因此可以安全地在方法中使用它们。
  • 使用箭头函数和 bind() 可以使用 bind() 方法显式地将箭头函数的 this 值绑定到 class 的实例。
class Person {
  constructor(name) {
    this.name = name;
  }

  // 使用常规函数
  greet() {
    console.log(`Hello, my name is ${this.name}.`);
  }

  // 使用箭头函数和 bind()
  greetArrow = () => {
    console.log(`Hello, my name is ${this.name}.`);
  }.bind(this);
}

const person = new Person("John");
person.greet(); // Output: Hello, my name is John.
person.greetArrow(); // Output: Hello, my name is John.