ECMAScript 2021 中 this 的难点探讨

阅读时长 8 分钟读完

作为前端开发者,我们都知道 this 是 JavaScript 中一个非常重要的关键字,也是初学者常常觉得困惑的语法之一。实际上,在 ECMAScript 2021 中,this 依然是一个容易被忽略难点。在本文中,我们将深入探讨 this 的用法和难点,并提供一些实际的例子和指导意义。

什么是 this?

this 是指向当前函数执行的环境对象的一个关键字。它与普通变量的区别在于,它的值在函数调用的时候才能确定。

在 JavaScript 中,有四种情况下使用 this

  1. 函数作为对象的方法调用,this 指向这个对象
  1. 直接调用函数,this 指向 windowglobal
  1. 通过 applycallbind 改变函数的上下文,this 指向指定的对象
-- -------------------- ---- -------
----- ------- - -
  ----- -----
-
----- ------- - -
  ----- -------
-
-------- --------- -
  -----------------------
-
---------------------- -- -----
----------------------- -- -------
----- ---------- - ----------------------
------------- -- -----
  1. 作为构造函数调用,this 指向新创建的对象

ECMAScript 2021 的新特性

在 ECMAScript 2021 中,新增了一些关于 this 的特性,让我们更加方便地使用它。

箭头函数的 this

在普通函数中,this 的值是在函数被调用的时候决定的。而在箭头函数中,this 的值是在声明时决定的。这意味着,在箭头函数中使用 this 时,它指向的是函数声明时所在的上下文。

-- -------------------- ---- -------
----- ------ - -
  ----- ------
  --------- -
    ----- -------- - -- -- -
      --------------------- - - ---------
    --
    -----------
  -
-
----------------- -- ---- -------

在这个例子中,我们定义了一个箭头函数 fullName,并在 sayName 中调用它。由于 fullName 是在 sayName 中定义的,而 sayName 是作为 person 对象的方法调用的,所以 this 指向的是 person 对象。因此,this.name 的值为 'Tom'

静态方法的 this

在 ECMAScript 2021 中,我们可以使用 this 来引用静态方法内部的其他静态方法,而不必使用类名或对象名。这种方式使得代码更加可读且易于维护。

-- -------------------- ---- -------
----- ------ -
  ------ ---------- -
    ------------------- - - ------------------
  -
  ------ --------- -
    ------ ------
  -
-
------------------ -- ------- ----

在这个例子中,我们定义了一个 Person 类,其中包含两个静态方法 sayHellogetName。我们可以看到,在 sayHello 中使用了 Person.getName 来调用 getName 方法。而在 ECMAScript 2021 中,我们可以使用 this.getName() 来代替 Person.getName()。这种方式使得代码更加清晰易懂。

经典难题:this 指向问题

尽管我们已经了解了 this 的基本用法和 ECMAScript 2021 中的新特性,但仍然有一些比较经典的难点仍然需要深入探讨。下面是其中几个例子:

setTimeout 中的 this

在这个例子中,我们定义了一个 person 对象,并调用了它的 sayName 方法。我们还通过 setTimeout 函数来实现延迟执行。然而,我们将 person.sayName 传递给 setTimeout,这样在执行 sayName 方法的时候,this 就变成了 window。因此控制台输出 undefined,而不是 'Tom'

解决这个问题的方法是通过箭头函数来定义一个包裹函数,将 person.sayName 作为参数传递进去。这样,在执行箭头函数的时候,this 仍然指向 person 对象。

点击事件中的 this

在这个例子中,我们使用 addEventListener 函数为按钮添加了一个点击事件监听。我们还定义了一个匿名函数来作为点击事件回调函数,用于输出当前的 this 对象。然而,在这种情况下,this 实际上指向的是触发事件的 DOM 元素(即按钮),而不是我们希望的回调函数内部定义的 this。这可能会导致一些错误,例如无法访问我们希望的对象。

解决这个问题的方法是使用箭头函数。箭头函数中的 this 始终指向定义时所在的上下文,而不是执行时的上下文。因此,使用箭头函数来定义回调函数可以解决这个问题。

map 中的 this

-- -------------------- ---- -------
----- ------ - -
  ----- ------
  -------- --------- ------- --------
  ------------- -
    --------------------------------- -
      --------------------- - - --- -- -- - - --------
    ---
  -
-
---------------------
-- --------- --- -- -- -----
-- --------- --- -- -- ----
-- --------- --- -- -- ----

在这个例子中,我们定义了一个 person 对象,它有一个 listFriends 方法,用于遍历所有朋友,并向他们问好。我们在 map 中使用了一个匿名函数来实现,但是在匿名函数中,this 的值已经改变,不再指向 person 对象。

解决这个问题的方法是使用箭头函数。箭头函数中的 this 始终指向定义时所在的上下文,而不是执行时的上下文。因此,使用箭头函数来定义回调函数可以解决这个问题。

-- -------------------- ---- -------
----- ------ - -
  ----- ------
  -------- --------- ------- --------
  ------------- -
    ------------------------- -- -
      --------------------- - - --- -- -- - - --------
    ---
  -
-
---------------------
-- --- --- -- -- -----
-- --- --- -- -- ----
-- --- --- -- -- ----

总结

本文深入探讨了 this 的基本用法和 ECMAScript 2021 中的新特性,并给出了一些经典难题的解决方案。通过深入探讨和实际的例子,我们可以更好地理解 this 的概念和用法,也可以更加高效地使用它来开发我们的前端应用程序。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/646ed525968c7c53b0d37a92

纠错
反馈