在前端开发中,ES6 的箭头函数已经成为了很多开发者的喜欢之选。但是,在实际开发过程中,我们也经常会遇到箭头函数与 this 指向不一致的问题,特别是当箭头函数作为对象方法时。本文将会详细讨论此问题,并给出相应的解决方案。
箭头函数与 this 指向
在 ES6 之前,我们在对象方法内部需要通过 this 来访问对象的属性或者调用对象的方法,比如:
const person = { firstName: 'John', lastName: 'Doe', getFullName: function() { return this.firstName + ' ' + this.lastName; } }
在这个例子中,我们定义了一个 person 对象,并在对象的 getFullName 方法中使用了 this 关键字来获取对象的属性值。当我们调用方法时:
console.log(person.getFullName()); // 输出 'John Doe'
代码能够很好的工作。
然而,当我们使用箭头函数定义对象的方法时,情况就变得有些复杂了:
const person = { firstName: 'John', lastName: 'Doe', getFullName: () => { return this.firstName + ' ' + this.lastName; } }
当我们再次尝试运行之前的代码时:
console.log(person.getFullName()); // 输出 'undefined undefined'
这是因为在箭头函数中,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