首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

编写高质量箭头函数的5个优秀做法

箭头功能值得流行。 它的语法简洁明了,使用词法绑定绑定 this,它非常适合作为回调。在本文中,通过了解决学习5个最佳实践,以便我们可以从中学习更多箭头函数的知识,并从它身上获得更多的好处。

1. 箭头函数名推断

JS 中的箭头函数是?匿名(anonymous)?的:函数的?name?属性是?''?。

代码语言:javascript
复制
(?number?=>?number?+?1?).name;?//?=>?''?

在调试会话或调用堆栈分析期间,匿名函数被标记为?anonymous?。 不幸的是,?anonymous?程序不提供有关正在执行的代码的任何线索。

这里是执行匿名函数的代码的调试会话:

右边的调用堆栈由两个标记为?anonymous?的函数组成,我们无法从这样的调用堆栈信息中获得任何有用的信息。

幸运的是,函数名推断(ES2015的功能)可以在某些条件下检测到函数名称。 名称推断的思想是JS 可以从其语法位置确定箭头函数名称: 从保存函数对象的变量名称中获取。

我们来看看函数名称推断的工作原理:

代码语言:javascript
复制
const?increaseNumber?=?number?=>?number?+?1;??increaseNumber.name;?//?=>?'increaseNumber'?

因为变量?increaseNumber?保存了箭头函数,所以 JS 决定使用?increaseNumber?作为该函数的名称。因此,箭头函数的名称为?'increaseNumber'?。

第1个实践:

一个好的做法是使用函数名称推断来命名箭头函数。

现在我们用使用名称推断的代码检查一个调试会话:

因为箭头函数有名称,所以调用堆栈提供了有关正在执行的代码的更多信息。

代码语言:javascript
复制
handleButtonClick?gainCounter?

2.尽可能使用内联方式

内联函数是仅具有一个表达式的函数。 我喜欢箭头功能,可以编写短内联函数。

例如,不要使用箭头函数的长形式:

代码语言:javascript
复制
const?array?=?[1,?2,?3];??array.map((number)?=>?{????return?number?*?2;?});?

当箭头函数只有一个表达式时,可以轻松地删除大括号?{}?和?return?语句:

代码语言:javascript
复制
const?array?=?[1,?2,?3];??array.map(number?=>?number?*?2);?

第2个实践:

当函数只有一个表达式时,一个好的做法是使用内联箭头函数格式

3.胖箭头和比较运算符

比较操作符?>?、?<?、?<=?和?>=?看起来类似于f胖箭头?=>?(它定义了箭头函数)。当在内联箭头函数中使用这些比较操作符时,会产生一些混淆。

例如我们定义一个使用?<=?操作符的箭头函数

代码语言:javascript
复制
const?negativeToZero?=?number?=>?number?<=?0???0?:?number;?

同一行上的两个符号?=>?和?<=?的存在会引起误解。

为了清楚地将胖箭头与比较操作符区分开,我们可以使用圆括号:

代码语言:javascript
复制
const?negativeToZero?=?number?=>?(number?<=?0???0?:?number);?

第二个选项是使用更长的形式来定义箭头函数:

代码语言:javascript
复制
const?negativeToZero?=?number?=>?{???return?number?<=?0???0?:?number;?};?

这些重构消除了胖箭头符号和比较操作符之间的混淆。

第3个实践:

如果箭头函数包含操作符?>?、?<?、?<=?和?>=?,一个好的做法是将表达式包装成一对括号,或者故意使用更长的箭头函数形式。

4.构造普通对象

在内联箭头函数中使用对象字面量会触发语法错误:

代码语言:javascript
复制
const?array?=?[1,?2,?3];??//?throws?SyntaxError!?array.map(number?=>?{?'number':?number?});?

JS 认为花括号是代码块,而不是对象文字。

将对象字面量加上一对括号即可解决此问题:

代码语言:javascript
复制
const?array?=?[1,?2,?3];??//?Works!?array.map(number?=>?({?'number':?number?}));?

如果对象字面量有很多属性,我们可以使用换行,同时仍然保持箭头函数内联

代码语言:javascript
复制
const?array?=?[1,?2,?3];??//?Works!?array.map(number?=>?({???'number':?number???'propA':?'value?A',???'propB':?'value?B'?}));?

第4个实践:

在内联箭头函数中使用对象时,把改对象包装在一对括号中。

5.注意过多的嵌套

箭头函数的语法很短,很好。 但是,副作用是,当许多箭头函数嵌套时,它可能是晦涩难懂。

我们考虑以下情况。 单击按钮后,启动对服务器的请求,响应准备就绪后,将各项记录到控制台:

代码语言:javascript
复制
myButton.addEventListener('click',?()?=>?{???fetch('/items.json')?????.then(response?=>?response.json());?????.then(json?=>?{???????json.forEach(item?=>?{?????????console.log(item.name);???????});?????});?});?

这里有三层箭头函数的嵌套,需要花时间和精力来了解代码的作用。

为了提高嵌套函数的可读性,第一种方法是引入每个包含箭头函数的变量,该变量应简明地描述函数的功能。

代码语言:javascript
复制
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);?

重构将箭头函数提取到变量?readItemsJson?和?handleButtonClick?中。 嵌套级别从3减少到2。现在,我们可以更轻松地了解脚本的功能。

更好的是,可以使用?async/await?语法重构整个函数,这是解决函数嵌套的一个很好的方法:

代码语言:javascript
复制
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);?

第5个实践:

避免箭头函数过多的嵌套,好的做法是通过将箭头函数提取为独立函数,或者尽可能使用?async/await?语法。

6. 总结

JS中的箭头函数是匿名的。为了使调试更高效,一个好的实践是使用变量来保存箭头函数,这允许JS 推断函数名。

当函数主体具有一个表达式时,嵌入式箭头函数非常方便。

操作符?>?、?<?、?<=?和>=看起来类似于胖箭头?=>?,在内联箭头函数中使用这些操作符时必须小心。

对象字面量语法?{prop:'value'}?与代码块?{}?相似。 因此,当将对象字面量放置在嵌入式箭头函数中时,需要将其包装在一对括号中:?()=>({prop:'value'})?。

最后,函数的过度嵌套模糊了代码意图。减少箭头函数嵌套的一个好方法是将它们提取到变量中。或者,尝试使用更好的特性,如?async/await?语法。

对于箭头函数,你还有什么建议,欢迎留言讨论。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具?Fundebug?。

原文:?https://dmitripavlutin.com/ja...

  • 发表于:
  • 原文链接http://news.51cto.com/art/202002/610593.htm
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券
http://www.vxiaotou.com