如何优雅地使用 ES6 箭头函数

作者 : 开心源码 本文共2446个字,预计阅读时间需要7分钟 发布时间: 2022-05-13 共183人阅读

箭头函数以其简洁的语法、没有烦人的this问题而广受欢迎,非常适合用作回调函数。

本文将详情5个最佳实践方法,帮你用好箭头函数。

1. 箭头函数名称推断

JavaScript 中的箭头函数是匿名函数:函数的name 属性是空字符串''

( number => number + 1 ).name; // => ''

匿名函数在调试过程中和调用栈分析里被标记为anonymous 。很遗憾,anonymous 对执行中的代码没有提供任何追踪信息。

下面是代码中执行匿名函数的调试截图:

image.png

右边的调用栈包含2个标记为anonymous 的函数。从这样的调用栈里你无法得到任何有用的信息。

所幸的是,函数名称推断(ES2015 的特性)可以在特定条件下检测到函数名称。名称推断是指,JavaScript 可以从其语法位置确定箭头函数名:例如,从指向函数对象的变量名得到。

我们来看看函数名称推断是怎样工作的:

const increaseNumber = number => number + 1;increaseNumber.name; // => 'increaseNumber'

因为变量 increaseNumber指向这个箭头函数,JavaScript 就认为 'increaseNumber' 可以作为这个函数的名称。

现在我们来看使用了名称推断后的调试过程:

由于箭头函数有名称了,调用栈即可以给出运行中的代码的更多信息:

  • handleButtonClick 这个函数名称表明某个点击事件被触发了
  • increaseCounter 添加计数器变量

2. 尽量使用内联形式

内联函数是只有一个表达式的函数。我比较喜欢箭头函数的内联形式。

例如,不使用完整形式的箭头函数:

const array = [1, 2, 3];array.map((number) => {   return number * 2;});

而是去掉花括号{ }return 语句,只保留一个表达式:

const array = [1, 2, 3];array.map(number => number * 2);

我的建议是:

当函数只有一个表达式时,尽量使用内联形式

3. 当箭头符号遇上比较符号

用于比较的运算符 ><<=>=看起来跟箭头符号=>很像,这些符号用在内联箭头函数里面容易造成混淆,影响阅读。

比方这个:

const negativeToZero = number => number <= 0 ? 0 : number;

=><=这两个符号出现在同一行里可能会误导人。

为了清楚地区分这两个符号,第一种做法是用圆括号把表达式括起来:

const negativeToZero = number => (number <= 0 ? 0 : number);

第二种做法是刻意使用完整形式的箭头函数:

const negativeToZero = number => {  return number <= 0 ? 0 : number;};

这样箭头符号和比较符号就不容易混淆了。

4. 内联表达式中的对象字面量

内联箭头函数里的对象字面量这样写会导致语法错误:

const array = [1, 2, 3];// throws SyntaxError!array.map(number => { 'number': number });

JavaScript 认为这里的花括号是代码块,而不是对象字面量。假如是这种情况,怎样在内联表达式里返回对象字面量呢?外面加一层圆括号就行了:

const array = [1, 2, 3];// Works!array.map(number => ({ 'number': number }));

假如对象字面量有很多个属性,你可以每行写一个,这样保持内联形式的同时,可读性更好:

const array = [1, 2, 3];// Works!array.map(number => ({  'number': number  'propA': 'value A',  'propB': 'value B'}));

5. 减少多层嵌套

箭头函数语法简洁,这个很好。但是也有反作用,就是容易写成多层嵌套,这样就会导致相似“回调地狱”的问题。

来看下面这个例子:

myButton.addEventListener('click', () => {  fetch('/items.json')    .then(response => response.json());    .then(json => {      json.forEach(item => {        console.log(item.name);      });    });});

嵌套了3层箭头函数,要了解代码的用意就比较费劲和费时。

为了提高嵌套函数的可读性,第一种方法是给每个箭头函数指定一个变量。这些变量需要精确形容函数的功能。

const readItemsJson = json => {  json.forEach(item => console.log(item.name));};const handleButtonClick = () => {  fetch('/items.json')    .then(response => response.json());    .then(readItemsJson);};myButton.addEventListener('click', handleButtonClick);

重构后的代码把箭头函数提取到了 readItemsJsonhandleButtonClick 变量中。嵌套由3层降低到2层,现在就更容易了解代码的用意了。

甚至更进一步,你可以用async/await语法重构整个函数,这样彻底不需要嵌套了:

const handleButtonClick = async () => {  const response = await fetch('/items.json');  const json = await response.json();  json.forEach(item => console.log(item.name));};myButton.addEventListener('click', handleButtonClick);

更多前台技术干货尽在微信公众号:1024译站

微信公众号:1024译站

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 如何优雅地使用 ES6 箭头函数

发表回复