返回

用直观方法梳理JavaScript中的this

前端


JavaScript 中的 this 是容易让人混淆的概念之一,本篇博客中将尽量用直观的方式讲解 this

了解this

所有的函数在被调用时,都会创建一个执行上下文,这个上下文中记录着函数的调用栈、函数的调用方式、传入的参数信息等;this也是其中的一个属性。
函数在调用时,this 会被赋予一个值,这个值是由函数的调用方式决定的,一共有如下几种情况:

  • 当函数作为对象的方法被调用时,this 被赋予这个对象。
  • 当函数作为构造函数被调用时,this 被赋予一个新创建的对象。
  • 当函数作为普通函数被调用时,this 被赋予全局对象(在浏览器中,全局对象是 window)。

对象方法

当函数作为对象的方法被调用时,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 对象。

构造函数

当函数作为构造函数被调用时,this 被赋予一个新创建的对象。构造函数的调用方式与普通函数不同,它需要使用 new 关键字。

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

const person1 = new Person("John Doe");
const person2 = new Person("Jane Doe");

person1.greet(); // "Hello, my name is John Doe"
person2.greet(); // "Hello, my name is Jane Doe"

在这个例子中,Person 函数作为构造函数被调用,所以 this 被赋予一个新创建的对象,这个对象存储着 namegreet 属性。

普通函数

当函数作为普通函数被调用时,this 被赋予全局对象(在浏览器中,全局对象是 window)。

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

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

在这个例子中,greet 函数作为普通函数被调用,所以 this 被赋予全局对象,而全局对象中没有 name 属性,所以 this.name 的值为 undefined

箭头函数

箭头函数没有自己的 this 值,它会继承外层函数的 this 值。

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

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

在这个例子中,greet 函数是箭头函数,它继承了 person 对象的 this 值,所以 this.name 的值为 John Doe

总结

this 关键字是 JavaScript 中一个容易让人混淆的概念,但只要理解了它的基本原理,就很容易掌握。

希望这篇文章能帮助你更好地理解 this 关键字。如果您有任何问题,请随时在评论区留言。