【翻译】深入理解ES6:箭头函数

深入理解ES6 是介绍ECMAScript 6.0版标准(简称 ES6)中加入到JavaScript编程语言新特性的系列文章。

箭头在一开始就已经成为JavaScript的一部分。在最开始的JavaScript教程就建议把行内脚本包裹在HTML注释里面。这将会阻止不支持JS的浏览器错误地将JS代码显示在文本中。你可能会这样子写:

1
2
3
4
5
<script language="javascript">
<!--
document.bgColor = "brown"; // red
// -->
</script>

旧的浏览器将会解析成两个不支持的标签和一段注释;而新的浏览器将会解析成JS代码。

为了支持这种古怪的技巧,浏览器中的JavaScript引擎将会把字符 <!– 当作单行注释的开始。这并不是在开玩笑,而是一直以来都是JavaScript语言的一部分,直到现在,不仅仅是在行内<script>标签的顶部能够正常运行,而且是在JS代码的任何地方,甚至包括在Node中。

碰巧的是这种风格的注释第一次在ES6中被标准化。不过这不是我们在这里谈论的箭头。

箭头序列 –> 也表示一个单行注释。奇怪的是,在HTML中,–>之前的字符表示注释的一部分,而在JS中,–> 所在行后面剩下的部分表示注释。

这变得更奇怪了。只有当 –> 箭头出现在一行的开始部分,它才表示一个注释。这是因为在别的JS上下文中,–> 是一个操作符,表示“goes to”。

1
2
3
4
5
function countdown(n) {
while (n --> 0) // "n goes to zero"
alert(n);
blastoff();
}

上面的代码是真的能够运行的。当n变成0的时候,循环才会停止。这不是ES6的新特性,而是已有特性的组合,所以会带来一点误导。你能弄清楚这是怎么回事吗?照例你可以在Stack Overflow上找到问题的答案。

当然还有一个小于或等于的操作符,<=。也许你能够在你的JS代码中找出更多的箭头,但是我们就此打住,你应该注意到我们遗落了一个箭头符号。






<!– single-line comment
–> “goes to” operator
<= less than or equal to
=> ???

=> 操作符到底发生了什么?今天我们就要探究这个问题。

首先我们先谈论下函数。

###无处不在的函数表达式

JavaScript中一个有趣的特性是,任何时候,当你需要一个函数,你只需在运行的代码的右侧输入函数就可以。

举个例子,假设你正打算让用户点击了浏览器上特定按钮的时候,浏览器做点什么,于是你敲了下面的代码:

1
$("#confetti-btn").click(

jQuery的 .click() 方法需要一个参数:一个函数。没问题,你正好在右侧输入一个函数:

1
2
3
4
$("#confetti-btn").click(function (event) {
playTrumpet();
fireConfettiCannon();
});

这样子写代码对我们现在来说是相当自然而然的。在JavaScript推广这种编程方式之前,很多语言都没有这种特征,所以我们会觉得很奇怪。当然Lisp早在1958年就有函数表达式,也称作lambda函数。但是像 C++、Python、C#以及Java在很长的时间里是没有函数表达式。

现在,上面的四种语言不再没有lambda函数了。新出现的编程语言无一例外地拥有内建的lambda函数。我们得感谢JavaScript和早期的JavaScript程序员,因为他们无畏地建立了许多严重依赖lambda的函数库,并且使得这种特征被广泛地采纳。

然而略带忧伤的是,上面我所提到的编程语言中,JavaScript的lambda函数语法被证明是最啰嗦的。

1
2
3
4
5
6
7
// A very simple function in six languages.
function (a) { return a > 0; } // JS
[](int a) { return a > 0; } // C++
(lambda (a) (> a 0)) ;; Lisp
lambda a: a > 0 # Python
a => a > 0 // C#
a -> a > 0 // Java