JavaScript:箭头函数与this关键词
那么,到底是什么=>?
你可能在这里或那里见过这些奇怪的埃及象形文字符号,尤其是在别人的代码中,你正在调试一个“this”关键字问题。经过一个小时的修补,你现在漫游谷歌搜索栏和跟踪堆栈溢出。听起来熟悉吗?
让我一起来讨论3个主题:
- “this”关键字与=>的关系
- 如何将函数从ES5迁移到ES6。
- 使用=>时要注意的重要技巧。
箭头函数
创建箭头函数是为了简化函数的作用域,并使用“this”关键字更加简单。它们使用看起来像箭头的=>;语法。尽管我不认为它需要节食,但人们称之为“胖箭头”(Ruby爱好者可能更了解它为“散列火箭”)——这是需要注意的。
“this”关键字与箭头函数的关系
在深入研究ES6 arrow函数之前,首先要清楚地了解ES5代码中的“this”绑定到什么
如果“this”关键字位于对象的方法(属于对象的函数)中,那么它将指什么?
1 | // Test it here: <https://jsfiddle.net/maasha/x7wz1686/> |
对的!它指的是那个对象(bunny)。我们稍后再讨论原因。
如果’this’关键字在方法的函数中呢?
1 | // Test it here: <https://jsfiddle.net/maasha/z65c1znn/> |
你得到了什么?等等,我们的bunny怎么了…?
啊,你认为‘this’是指方法的内部函数吗?
也许是对象本身?
你这么想是明智的,但事实并非如此。请允许我教你老程序员曾经教过我的:
老程序员:“啊,是的,这个代码很强,认为’this’关键字绑定到函数确实是可行的,但事实是,’this’现在已经超出了范围…它现在属于…”。他停顿了一下,好像经历了内心的混乱,“window对象”
没错。事情就是这样发生的。
“this”为什么绑定到window对象?因为“this”总是引用它所在的函数的所有者,在这种情况下,因为它现在超出了范围,所以是window/global对象。
当它位于对象的方法内部时,函数的所有者就是该对象。因此,“this”关键字被绑定到该对象。然而,当它在一个函数内部时,不管是独立的还是在另一个方法中,它总是引用window/global对象。
1 | // Test it here: <https://jsfiddle.net/maasha/g278gjtn/> |
但是为什么…?
这被称为Java脚本怪癖,这意味着Java脚本中发生的事情并不完全简单,而且它的工作方式不符合您的想法。开发人员也认为这是一个糟糕的设计选择,他们现在正在用ES6的箭头函数来重新定义它。
在我们继续之前,重要的是要了解程序员解决ES5代码中“this”问题的两种灵巧方法,特别是因为您将继续在ES5中运行一段时间(并非所有浏览器都已完全迁移到ES6):
- 在方法的内部函数之外创建一个变量。现在,“for Each”方法获得了对“this”的访问,从而获得对象的属性及其值。这是因为“This”存储在变量中,而它仍然在对象的直接方法“showTasks”的范围内。
1 | // Test it here: <https://jsfiddle.net/maasha/3mu5r6vg/> |
- 使用bind将引用该方法的“this”关键字附加到该方法的内部函数。
1 | // Test it here: <https://jsfiddle.net/maasha/u8ybgwd5/> |
现在介绍…箭头函数!处理“this”问题从未如此简单和直接!简单的ES6解决方式:
1 | // Test it here: <https://jsfiddle.net/maasha/che8m4c1/> |
在ES5中,“this”指的是函数的父级,而在ES6中,箭头函数使用词法范围-“this”指的是它当前的周围范围,而不是其他范围。因此,内部函数只知道绑定到内部函数,而不绑定到对象的方法或对象本身。
如何将函数从ES5迁移到ES6。
1 | // Before |
你做到了!干得好!很简单吧?下面是更多利用胖-瘦箭头的例子,让你的眼睛习惯:
1 | // #1 ES6: if passing one argument you don't need to include parenthesis around parameter. |
使用箭头函数时要注意的重要技巧
如果将“new”关键字与=>函数一起使用,则会引发错误。箭头函数不能用作构造函数-普通函数通过属性原型和内部方法[[Construct]]支持“new”。箭头函数两者都不使用,因此新的(()=>{})抛出一个错误。
需要考虑的其他问题:
1 | // Line breaks are not allowed and will throw a syntax error |
恭喜!你已经通过了学习ES6的Dope Way第二部分,现在你有了箭头函数知识的基础,它给’this’带来的词汇上的好处,同时你也学到了一些Java脚本的技巧!:)
保持你的智慧更新喜欢和跟随更多学习ES6的方式即将到来的!
后记
翻译自Learn ES6 The Dope Way Part II: Arrow functions and the ‘this’ keyword