返回

JavaScript 之你不知道的 this

前端

this 是 JavaScript 中一个非常重要的概念, 但它也常常让人感到困惑。这可能是因为 this 是一个动态的值, 它根据函数的调用方式而变化。

在 JavaScript 中, 有四种主要的方式可以调用函数:

  • 作为对象的方法调用
  • 作为函数本身调用
  • 使用 new 操作符调用
  • 使用 bind()、call() 或 apply() 方法调用

作为对象的方法调用

当一个函数作为对象的方法被调用时, this 被设置为该对象。例如, 考虑以下代码:

const person = {
  name: "John Doe",
  greet: function() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

person.greet(); // "Hello, my name is John Doe"

在上面的代码中, greet() 函数作为 person 对象的方法被调用。因此, this 被设置为 person 对象, 并且我们可以访问 person 对象的属性, 如 name。

作为函数本身调用

当一个函数作为函数本身被调用时, this 被设置为全局对象。在浏览器中, 全局对象是 window 对象。在 Node.js 中, 全局对象是 global 对象。

例如, 考虑以下代码:

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

greet(); // "Hello, my name is undefined"

在上面的代码中, greet() 函数作为函数本身被调用。因此, this 被设置为全局对象, 并且我们无法访问全局对象的 name 属性。

使用 new 操作符调用

当一个函数使用 new 操作符调用时, this 被设置为一个新创建的对象。这个对象是函数的实例。

例如, 考虑以下代码:

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

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

const person = new Person("John Doe");

person.greet(); // "Hello, my name is John Doe"

在上面的代码中, Person() 函数使用 new 操作符被调用。因此, this 被设置为一个新创建的 Person 对象。这个对象是 Person() 函数的实例。

使用 bind()、call() 或 apply() 方法调用

当一个函数使用 bind()、call() 或 apply() 方法被调用时, this 可以被显式地设置为任何值。

例如, 考虑以下代码:

const person = {
  name: "John Doe"
};

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

greet.call(person); // "Hello, my name is John Doe"

在上面的代码中, greet() 函数使用 call() 方法被调用。this 被显式地设置为 person 对象。因此, 我们可以访问 person 对象的 name 属性。

结论

this 是 JavaScript 中一个非常重要的概念, 但它也常常让人感到困惑。这可能是因为 this 是一个动态的值, 它根据函数的调用方式而变化。

在本篇文章中, 我们深入探讨了 this , 揭开了它背后的秘密, 并提供了