ES8 之箭头函数在对象方法内 this 指向问题

阅读时长 5 分钟读完

在前端开发中,ES6 的箭头函数已经成为了很多开发者的喜欢之选。但是,在实际开发过程中,我们也经常会遇到箭头函数与 this 指向不一致的问题,特别是当箭头函数作为对象方法时。本文将会详细讨论此问题,并给出相应的解决方案。

箭头函数与 this 指向

在 ES6 之前,我们在对象方法内部需要通过 this 来访问对象的属性或者调用对象的方法,比如:

在这个例子中,我们定义了一个 person 对象,并在对象的 getFullName 方法中使用了 this 关键字来获取对象的属性值。当我们调用方法时:

代码能够很好的工作。

然而,当我们使用箭头函数定义对象的方法时,情况就变得有些复杂了:

当我们再次尝试运行之前的代码时:

这是因为在箭头函数中,this 关键字被绑定到了定义箭头函数的词法作用域,也就是全局作用域。因此,在箭头函数中,this 指向的是全局对象,而不是 person 对象。

解决方案

要解决这个问题,最简单的办法就是使用 ES6 之前的函数定义方式,即使用 function 关键字来定义对象的方法。但这不是一个好的解决方案,因为 ES6 的箭头函数有许多其他的优点。

另一种解决方案是使用 bind 函数来手动设置 this 的值:

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

在这个例子中,我们定义了一个新的方法 getFullNameArrow,并使用箭头函数来实现。我们通过手动调用 bind 函数来设置 this 的值,从而解决了箭头函数中 this 指向问题。在调用 getFullNameArrow 方法时,代码能够正确地输出对象的属性值。

另一种解决方案则是使用 ES7 之前的方法,即全局替换 this,把函数体中的所有 this 都替换掉:

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

在这个例子中,我们使用一个变量 that 来保存 this 的值,然后在返回的函数中使用该变量来获取对象的属性值。这种方式虽然可行,但是比较麻烦,而且很容易出现错误。

总结

使用箭头函数时需要注意它们的 this 关键字在词法作用域中被绑定的情况。如果箭头函数作为对象方法使用,那么 this 将指向全局对象。为了解决这个问题,我们可以使用 bind 函数,手动设置 this 的值,或者使用传统的函数定义方式。为了避免 this 指向的问题,我们应该在编写代码时尽可能地避免使用箭头函数作为对象方法。

示例代码

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

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

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

纠错
反馈