如果你已经接触过 ES6 及以上的版本,那么你一定会使用过箭头函数。然而,受限于一些老旧的浏览器和版本,箭头函数并不能在所有场景下正常地运行。同时,如果使用了 Babel 转换器来将代码翻译成更低版本的 JavaScript,你也可能遇到一些问题。在本篇文章中,我们将会讨论如何解决在使用 Babel 转换箭头函数时发生的问题。
什么是 Babel?
首先,我们需要了解什么是 Babel。Babel 是一个广泛使用的 JavaScript 语法翻译器,它可以将 ES6+ 的代码,转化成向下兼容的 JavaScript 版本,使得我们可以在更广泛的浏览器和环境下使用这些特性。
Babel 的工作流程如下:
- 将代码解析成 AST(抽象语法树)
- 将 AST 转化成新的 AST (新的 AST 为 Babel 特有的格式)
- 将新的 AST 转化成代码
为什么会有问题?
然而,在转换箭头函数时,我们可能会遇到以下问题:
-- -------------------- ---- ------- ----- ------ - - ----- -------- -------- - --------- ---------- ------------ -- ----------- -- -- - --------------------- - - ----- - - -------------------- ---- - - --------------------
运行结果如下:
undefined likes coding, reading, travelling
我们本意是想要输出 Alice likes coding, reading, travelling
,但实际上输出的却是 undefined likes coding, reading, travelling
。这是因为箭头函数的 this
始终指向它所在上下文中的 this
对象,而不是函数自身的 this
。由于我们在上述代码中没有显式绑定 this
,所以 console.log
语句中的 this.name
和 this.hobbies
实际上都指向了 window
对象,因此 undefined
这个值就冒出来了。
在这种情况下,如果我们使用 Babel 将代码转换成 ES5 版本的代码,上述代码的结果将会是完全一样的:
-- -------------------- ---- ------- ----- ------ - - ----- -------- -------- - --------- ---------- ------------ -- ----------- -------- ------------ - --------------------- - - ----- - - -------------------- ---- - -- --------------------
运行结果同样为:
undefined likes coding, reading, travelling
这并不是我们想要的效果。因此,我们需要使用一些方法来解决这个问题。
解决方法
我们可以使用两种方法来解决这个问题。
切换至普通函数
首先,我们可以将箭头函数换成普通函数。这是最简单的方法,但它也可能会带来额外的问题:
-- -------------------- ---- ------- ----- ------ - - ----- -------- -------- - --------- ---------- ------------ -- ----------- ---------- - --------------------- - - ----- - - -------------------- ---- - -- --------------------
运行结果为:
Alice likes coding, reading, travelling
这种方法可能会受限于一些情况,例如当我们需要在函数内部访问外部变量时,或者当我们需要在保留 this
的同时使用 =>
符号时。因此,这种方法并不是总能适用。
使用 bind()
绑定 this
第二种方法是使用 bind()
来绑定 this
。bind()
方法将会返回一个新的函数,同时将原本函数中的 this
指向传递进来的参数。这种方法的优势在于它能够在保留箭头函数的同时正确地绑定 this
。
-- -------------------- ---- ------- ----- ------ - - ----- -------- -------- - --------- ---------- ------------ -- ----------- ---------- - --------------------- - - ----- - - -------------------- ---- -- ---------------- ---------- - ------ ---------------------- -- ------------- ----- ----------- -- --------------- ---------- - ------ -------------------------------- - ------ ------------- ----- --------- -------------- - -- -------------------- -- ----- ----- ------- -------- ---------- -------------------------------------- -- - ---------- ----- -------- ---------- ----- --------- ---------- ----- ----------- - ------------------------------------- -- - ------ ----- -------- ------ ----- --------- ------ ----- ----------- -
上述代码中,我们为 person
对象增加了两个方法,分别是 getHobbiesArrow()
和 getHobbiesBind()
。在 getHobbiesArrow()
方法中,我们使用了箭头函数求值。在 getHobbiesBind()
方法中,我们将函数用 bind()
方法绑定了 this
。运行结果显示,两种方法得到了不同的输出。
如果你需要对箭头函数使用绑定 this
的方法,可以将箭头函数放在一个常规函数中,然后再将常规函数绑定 this
。例如:
-- -------------------- ---- ------- ----- ------ - - ----- -------- -------- - --------- ---------- ------------ -- ----------- ---------- - --------------------- - - ----- - - -------------------- ---- -- -------------------- ---------- - ------ --------------------------------- - ------ -- -- ------------- ----- ---------- --------------- - -- ----------------------------------------------- -- -------
运行结果为:
[ 'Alice likes coding', 'Alice likes reading', 'Alice likes travelling' ]
在这个例子中,我们使用了糟糕的代码把箭头函数解构到一个常规函数中,然后再将常规函数绑定到 this
。虽然这不是最好的方案,但它可以让我们在箭头函数中继续使用 this
,并且在转换至 ES5 时不会出现问题。
结论
在使用 Babel 转换器时,箭头函数可能会出现绑定问题。我们可以通过将箭头函数替换成普通函数,或者将函数用 bind()
方法绑定来解决问题。虽然这些方法并不总是完美的,但它们可以帮助我们继续使用箭头函数,并且立即享受它们的简洁性和清晰性。
通过本文,您已经学会了如何解决在使用 Babel 转换箭头函数时发生的问题,相信这对于您的前端开发工作会有很大帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6737218c317fbffedf084cf6