箭头从一开始就一直是 JavaScript 的一部分. 第一个 JavaScript 教程建议在 html 注释中包装内联脚本. 这会阻止不支持 JS 的浏览器错误地将 JS 代码显示为文本. 你会写这样的东西:
<script language="javascript">
</script>
旧的浏览器会看到两个不支持的标签和评论; 只有新的浏览器会看到 JS 代码.
为了支持这种奇怪的黑客攻击, 浏览器中的 JavaScript 引擎对待这些字符也表示单行注释. 奇怪的是, 而在 HTML 中 ->之前的字符是注释, 在 JS 中, ->之后的其余部分是注释.
只有当它出现在一行的开头时, 此箭头才表示注释. 这是因为在其他情况下, ->是 JS 中的运算符,"递减至" 运算符!
- function countdown(n) {
- while (n --> 0) // "n goes to zero"
- alert(n);
- blastoff();
- }
循环运行直到 n 变为 0. 这也不是 ES6 中的一项新功能, 而是熟悉的功能的组合. 你能弄清楚这里发生了什么吗? 像往常一样, 这个难题的答案可以在 StackOverflow http://stackoverflow.com/questions/1642028/what-is-the-name-of-the-operator 中找到..
当然也有小于或等于运算符,<=. 也许你可以在你的 JS 代码中找到更多箭头.
函数表达式无处不在
JavaScript 的一个有趣功能是, 只要您需要某个功能, 您就可以在运行代码的中间直接键入该功能.
例如, 假设你试图告诉浏览器当用户点击一个特定的按钮时该做什么. 你开始输入:
$("#confetti-btn").click()
jQuery 的. click()方法有一个参数: function. 没问题. 你可以在这里输入一个函数:
- $("#confetti-btn").click(function (event) {
- playTrumpet();
- fireConfettiCannon();
- });
像这样编写代码现在对我们来说很自然. 所以很奇怪, 在 JavaScript 推广这种编程之前, 许多语言都没有这个功能. 当然, Lisp 在 1958 年有函数表达式, 也称为 lambda 函数. 但是 C ++,Python,C#和 Java 都存在多年, 没有它们.
令人震惊的箭头函数
ES6 引入了写入函数的新语法.
- // ES5
- var selected = allJobs.filter(function (job) {
- return job.isSelected();
- });
- // ES6
- var selected = allJobs.filter(job => job.isSelected());
当你只需要一个带有一个参数的简单函数时, 新的箭头函数语法就是 Identifier => Expression. 你可以跳过键入 function 并返回, 以及一些括号, 大括号和分号.
要用多个参数 (或者没有参数, 或者其他参数或者默认值, 或者一个解构参数) 来编写一个函数, 你需要在参数列表中添加括号.
要用多个参数 (或者没有参数, 或者其他参数或者默认值 https://hacks.mozilla.org/2015/05/es6-in-depth-rest-parameters-and-defaults/ , 或者一个解构参数 https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/ ) 来编写一个函数, 你需要在参数列表中添加括号.
- // ES5
- var total = values.reduce(function (a, b) {
- return a + b;
- }, 0);
- // ES6
- var total = values.reduce((a, b) => a + b, 0);
我觉得它看起来不错.
那么没有如此功能的设置呢? 箭头函数可以包含一个语句块, 而不仅仅是一个表达式. 回想一下我们之前的例子:
- // ES5
- $("#confetti-btn").click(function (event) {
- playTrumpet();
- fireConfettiCannon();
- });
以下是 ES6 的写法:
- // ES6
- $("#confetti-btn").click(event => {
- playTrumpet();
- fireConfettiCannon();
- });
请注意, 具有块体的箭头函数不会自动返回值. 为此使用返回语句.
使用箭头函数创建简单对象时有一个警告. 所以需要始终用圆括号包装对象:
- // create a new empty object for each puppy to play with
- var chewToys = puppies.map(puppy => {}); // BUG!
- var chewToys = puppies.map(puppy => ({})); // ok
不幸的是, 空对象 {} 和空块 {} 看起来完全一样. ES6 中的规则是 {紧跟在箭头后面总是被视为块的开始, 而不是对象的开始. 代码 puppy => {} 因此被默默地解释为一个不执行任何操作并返回未定义的箭头函数.
更令人困惑的是, 像 {key:value} 这样的对象文字看起来就像一个包含标签语句的块 - 至少, 这就是它对 JavaScript 引擎的外观. 幸运的是 "{" 是唯一不明确的字符, 所以用圆括号包装对象文字是你需要记住的唯一技巧.
这是什么?
普通函数函数和箭头函数之间的行为有一个细微的差别. 箭头函数没有 "this". 箭头函数的 "this" 总是从封闭范围继承.
在我们试图找出实际意义之前, 让我们稍微回顾一下.
让我们看看下面这个例子:
- {
- ...
- addAll: function addAll(pieces) {
- var self = this;
- _.each(pieces, function (piece) {
- self.add(piece);
- });
- },
- ...
- }
在这里, 你想在内部函数中使用 this.add(piece). 所以, 临时变量 self 用于将 "this" 外部值偷运到内部函数中. (另一种方法是在内部函数中使用. bind(this), 这两种方法都不是特别漂亮.)
在 ES6 中, 遵循以下规则:
对于将使用 object.method()语法调用的方法使用非箭头函数. 这些函数将会从调用者那里获得有意义的值.
- // ES6
- {
- ...
- addAll: function addAll(pieces) {
- _.each(pieces, piece => this.add(piece));
- },
- ...
- }
在 ES6 版本中, 请注意 addAll 方法从其调用者接收到此信息. 内部函数是一个箭头函数, 所以它从封闭范围继承此函数.
ES6 还提供了一种在对象文字中编写方法的更简便方法! 所以上面的代码可以进一步简化:
- // ES6 with method syntax
- {
- ...
- addAll(pieces) {
- _.each(pieces, piece => this.add(piece));
- },
- ...
- }
在方法和箭头之间, 我可能再也不会输入 "function" 了.
我什么时候可以使用箭头?
2013 年, 我通过 Firefox 实现了 ES6 箭头功能. Jan de Mooij 让他们快速完成工作. 感谢 Tooru Fujisawa 和 ziyunfei 的补丁.
箭头函数也在 Microsoft Edge 预览版中实现. 如果您有兴趣在 web 上使用它们, 它们也可以在 Babel http://babeljs.io/ ,Traceur https://github.com/google/traceur-compiler#what-is-traceur , 和 TypeScript http://www.typescriptlang.org/ 中使用.
来源: https://juejin.im/entry/5af95a6f51882542857eb6ff