深入理解JavaScript中的箭头函数

时间:2020-11-15 13:58:14 JavaScript 我要投稿

关于深入理解JavaScript中的箭头函数

  从一开始箭头就是 JavaScript 的一部分,在第一个 JavaScript 中就建议将内联的脚本代码包裹在 HTML 的注释中,这可以防止那些不支持 JavaScript 的浏览器错误滴将你的代码显示为明文。你也许写过下面这样的代码:

  古老的浏览器将看到两个不被支持的标签和一段注释,只有支持 JavaScript 的新浏览器才会将其解析为 JavaScript 代码。

  为了支持这个古怪的特性,浏览器的 JavaScript 引擎把  也表示一个单行注释,与 HTML 不同的是,在 HTML 中,--> 之前的部分是注释内容,而在 JavaScript 中,在 --> 之后的行才是注释。

  只有当 --> 出现在一行的开始时,才表示该箭头是一个注释,因为在其他情况下,--> 是一个操作符(goes to)。

  function countdown(n) { while (n-->0) // "n goes to zero" alert(n); blastoff();} function countdown(n) { while (n-->0) // "n goes to zero" alert(n); blastoff();}

  上面代码是真实能运行的。循环运行直到 n 为 0,这并不是 ES6 的新特性,但结合我们熟悉的特性,这具有很强的误导性。你能搞明白上面代码的运行情况吗?你可以在 Stack Overflow 上找到相应的解答。

  当然还有一个箭头,那就是小于等于操作符 <=,也许你还可以找到使用箭头的.地方,但我们还是停下来,看一个我们从没见过的箭头:

   goes to 操作符 <=> ???

  那么,=> 表示什么呢?这就是本文将讨论的话题。

  首先,我们来谈谈函数。

  无处不在的函数表达式

  JavaScript 一个有趣的特点是,任何时候你需要一个函数,你可以很方便地创建它们。

  例如,为一个按钮绑定点击事件:

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

  jQuery 的 .click() 方法需要一个函数作为参数,我们可以很方便地就地创建一个函数:

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

  现在对我们来说,编写这样的代码是最自然的事了。但是在 JavaScript 流行起来之前,这种风格的代码看起来还是有些奇怪,因为在其他语言中都没有这样的特性。在 1958 年,Lisp 就有了函数表达式,也叫 lambda 函数,而在存在多年的 C++、Python、C# 和 Java 中没有该特性。

  现在,这四门语言都有了 lambda 表达式,而且新出现的语言都普遍内置了 lambda 表达式。如今 JavaScript 也支持该特性了,这必须感谢那些重度依赖 lambda 表达式的库的开发者,这推动了该特性被广泛采纳。

  与其他几门语言相比,JavaScript 的语法略显冗长:

  // A very simple function in six languages.function (a) { return a > 0; } // JS[](int a) { return a > 0; } // C++(lambda (a) (> a 0)) ;; Lisplambda a: a > 0 # Pythona => a > 0 // C#a -> a > 0 // Java // A very simple function in six languages.function (a) { return a > 0; } // JS[](int a) { return a > 0; } // C++(lambda (a) (> a 0)) ;; Lisplambda a: a > 0 # Pythona => a > 0 // C#a -> a > 0 // Java

  箭头函数

  ES6 引入了一种新的语法来编写函数:

  // ES5var selected = allJobs.filter(function (job) { return job.isSelected();});// ES6var selected = allJobs.filter(job => job.isSelected()); // ES5var selected = allJobs.filter(function (job) { return job.isSelected();}); // ES6var selected = allJobs.filter(job => job.isSelected());

  当你需要只有一个参数的函数,箭头函数的语法可以简化为 Identifier => Expression,直接省略了 function 和 return 关键字,连括号和结尾的分号也同时省略了。

  编写一个有多个(或没有参数,或 Rest 参数和参数默认值,或解构参数)参数的函数,你需要用括号将参数括起来:

  // ES5var total = values.reduce(function (a, b) { return a + b;}, 0);// ES6var total = values.reduce((a, b) => a + b, 0); // ES5var total = values.reduce(function (a, b) { return a + b;}, 0); // ES6var total = values.reduce((a, b) => a + b, 0);

  箭头函数还可以与一些工具函数库完美地配合使用,比如 Underscore.js 和 Immutable,事实上,Immutable 文档中的例子全部都是使用 ES6 编写,其中有很多已经使用到了箭头函数。

  函数体除了使用一个表达式外,箭头函数还可以包含一个语句块,回忆之前我们提到过的例子:

  // ES5$("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon();}); // ES5$("#confetti-btn").click(function (event) { playTrumpet(); fireConfettiCannon();});

  下面是采用箭头函数的写法:

  // ES6$("#confetti-btn").click(event => { playTrumpet(); fireConfettiCannon();}); // ES6$("#confetti-btn").click(event => { playTrumpet(); fireConfettiCannon();});

  需要注意的是,使用语句块的箭头函数不会自动返回一个值,必须显式地使用 return 来返回一个值。

  还有一个忠告,当使用箭头函数来返回一个对象时,始终使用括号将返回的对象括起来:

  // create a new empty object for each puppy to play withvar chewToys = puppies.map(puppy => {}); // BUG!var chewToys = puppies.map(puppy => ({})); // ok // create a new empty object for each puppy to play withvar chewToys = puppies.map(puppy => {}); // BUG!var chewToys = puppies.map(puppy => ({})); // ok

  因为空对象 {} 与空语句块 {} 看上去一模一样,ES6 将始终把紧跟在 => 后面的 { 当作语句块的开始,而不是一个对象的开始,那么 puppy => {} 就被解析为一个没有函数体的箭头函数,而且返回值为 undefined。

【关于深入理解JavaScript中的箭头函数】相关文章:

1.深入理解Javascript中自执行匿名函数

2.深入理解javaScript中事件驱动

3.关于深入理解JavaScript中的对象的介绍

4.关于JavaScript中继承的深入理解

5.有关深入理解JavaScript中的并行处理的介绍

6.JavaScript中Function函数

7.JavaScript中exec函数用法

8.javascript中的函数分析