理解 JavaScript 中的“this”

2025-06-10

理解 JavaScript 中的“this”

如果理解不正确,JavaScript 中的关键字经常this会让人感到困惑。本文将this通过一些代码示例向您展示关键字的工作原理,以及如何在 JavaScript 的不同上下文中赋值。在不同的场景下,this关键字的值可能会发生变化:

      - `this` in a global context, function invocation

      - `this` in an object constructor

      - `this` in an object method.

      - `this` with arrow function (=>) 
Enter fullscreen mode Exit fullscreen mode

在跳到示例之前,我们先来看一下上下文,那么它在 JavaScript 中是什么呢? JavaScript 中的上下文始终是在代码执行过程中确定的值this。为了更清楚地理解,我们现在通过代码示例来了解它在每种情况下是如何工作的。

console.log("What is 'this' value?", this) // Window
function simpleFunction () {
   console.log("What is the value of this inside function?", this) //  Window
  }
simpleFunction()
Enter fullscreen mode Exit fullscreen mode

从代码示例 1this可以看出,全局对象是由执行上下文决定的,其中浏览器是全局对象(window)。同样,在函数内部调用函数时,this该函数引用的也是全局对象。但是this在构造函数内部,引用的又是什么呢?我们在下面的代码示例 2 中看到了这一点。

function Person(name, lastName) {
    this.name = name;
    this.lastName = lastName;
    this.displayName = function() {
       console.log(`Your name ${this.name} and lastName 
     ${this.lastName}`)
  }
}
  let person = new Person('George', 'Superman')
      person.displayName() // George Superman
Enter fullscreen mode Exit fullscreen mode

从上面的代码中我们看到,我们创建了一个构造函数Person,然后调用了一个新的实例对象georgethis在这种情况下,value 指的是新创建的对象。

let greetings = {
     word: 'Hello',
     printGreeting: function(){
       console.log("What 'this' refers to inside object method? ", 
   this.word) // "this" in object refers to the object itself- greetings
     }
  }

  greetings.printGreeting()
Enter fullscreen mode Exit fullscreen mode

从上面的代码示例 3 中,我们创建了一个具有属性和方法printGreeting 的对象。我们在方法内部调用属性名称this,其值指向对象本身。

我们从上面的代码示例中看到,this函数内部的值引用全局对象,对象方法内部的引用对象本身,但是如果我们想在另一个函数和引用中调用对象方法this,那么在这种情况下,的值是什么呢this?让我们看看代码示例 4,我们将在严格模式下运行它,如下所示

"use strict"
let person = {
    firstName: 'George',
 }

 function printName(greeting) {
  console.log(greeting + this.firstName)
 }

 printName('hello') // Uncaught TypeError: Cannot read property 'firstName' of undefined
Enter fullscreen mode Exit fullscreen mode

运行代码后,我们发现出现了错误,因为 JavaScript 解释器无法理解对象属性this.firstName,因为this函数内部的值是在执行上下文中设置的。但是,如何解决这个问题呢?JavaScript 函数是一种特殊类型的对象,它包含方法call()apply()bind()

call()、apply() 和 bind()

所有函数都会继承这些方法,以便在任何所需的上下文中获取值this。这些函数方法之间的区别在于:call()方法需要以逗号分隔的参数;apply() 方法以数组列表的形式传入,并且会立即执行;而 bind() 方法则可以稍后在任何所需的上下文中执行。下面的代码示例 5 展示了如何使用这些方法并this在任何所需的上下文中设置值。

  let person = {
    firstName: 'George',
  }

  function printName(greeting) {
    console.log(greeting + this.firstName);
  }

  printName.call(person, 'Hello') // Hello George
  printName.apply(person, ['Hello there']) // Hello there George
  let executeLater = printName.bind(person)
  executeLater() // George
Enter fullscreen mode Exit fullscreen mode

this使用箭头函数 =>

ECMAScript 2015(ES6)引入了箭头函数,使其成为 JavaScript 领域的一项新功能。使用箭头函数有很多好处,它简化了函数语法,无需绑定this。使用箭头函数时,函数this在封闭上下文中具有词法界限。让我们通过代码示例来直观地了解这一点。

let greetings = {
  word: 'Hello',
  printGreeting(){
      console.log(this.word)  // Hello
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

回到前面的代码示例 2,我们看到thisinside object 指的是对象本身,但如果我们需要问候语在 1 秒后显示,该怎么办?为了获得所需的结果,我们需要修改代码,如下所示

let greetings = {
  word: 'Hello',
  printGreeting(){
    window.setTimeout(function () {
      console.log(this.word) 

    }, 1000) // we can set bind(this)
  }
}

greetings.printGreeting() // undefined
Enter fullscreen mode Exit fullscreen mode

我们看到,执行printGreeting()方法后,结果为 undefined,因为setTimout()函数调用将this上下文设置为全局对象。然而,为了达到这个效果,我们可以使用前面提到的bind()方法,或者在setTimeout()函数之前创建一个闭包,并设置self=this 的值。不过,我们不需要这样做,因为我们可以使用箭头函数来实现所需的结果。


let greetings = {
  word: 'Hello',
  printGreeting(){
    window.setTimeout(() => {
      console.log(this.word)  
    }, 1000)
  }
}

greetings.printGreeting() // Hello

Enter fullscreen mode Exit fullscreen mode

现在,控制台上的结果将是问候语hello,因为使用箭头函数“ this ”绑定到封闭上下文,从而绑定到我们的“ greetings ”对象。

就是这样! :)

希望您觉得这篇文章有趣,并能帮助您理解thisJavaScript 及其在不同环境中的价值。

鏂囩珷鏉ユ簮锛�https://dev.to/naimlatifi5/understanding-this-in-javascript-cm2
PREV
像专业人士一样删除 Node 模块
NEXT
Top 10 Free Resources to Learn Data Structures and Algorithms in 2024 AWS Security LIVE!