请停止对 Array.reduce() 的恶意攻击

奋斗吧
奋斗吧
擅长邻域:未填写

标签: 请停止对 Array.reduce() 的恶意攻击

2023-07-24 18:23:28 129浏览

【编者按】这篇文章主要讨论了JavaScript 开发者是否应该使用 Array.reduce() 方法这个争议。作者认为,尽管有些人认为Array.reduce() 方法难以阅读和理解,但这主要是由于命名习惯的问题,而不是方法本身的问题。Array.reduce() 是一个强大的函数,可以做的远不止将数组每个元素执行一个操作,并返回一个累积的结果。作者通过举例和解释,阐述了他的观点,并对如何更好...

d900dc55c03af46dd1ce8f0a76c1b52f.gif

【编者按】这篇文章主要讨论了JavaScript 开发者是否应该使用 Array.reduce() 方法这个争议。作者认为,尽管有些人认为Array.reduce() 方法难以阅读和理解,但这主要是由于命名习惯的问题,而不是方法本身的问题。Array.reduce() 是一个强大的函数,可以做的远不止将数组每个元素执行一个操作,并返回一个累积的结果。作者通过举例和解释,阐述了他的观点,并对如何更好地使用 Array.reduce() 提出了建议。

原文链接: https://www.devchronicles.io/array-reduce-is-good/

未经允许,禁止转载!

作者 | SABIN ADAMS  译者 | 明明如月

责编 | 夏萌

出品 | CSDN(ID:CSDNnews)

最近 “JavaScript 开发者是否应该使用 Array.reduce() ”的话题, 在网上引发了很大争论。

下面是最近一次关于该问题的激烈讨论中的部分帖子:

“大家都承认 Array.reduce 是一个错误吗?” - rossipedia

“Epic Stack 在三个地方使用了 reduce,我并不感到羞耻。Array.reduce 很好。” - Kent C. Dodds

“虽然这个观点可能不讨喜,但我真的很讨厌 Array.reduce。我还发现,一个人越是愚蠢,他们就越认为 Array.reduce 是“有意义”和“重要”的。” - Chris Esplin

当然,每个人都可以有自己的观点!这篇文章旨在说明为什么所有认为 Array.reduce() 不好的观点都是错误的 ?。

免责声明:说Array.reduce 不好的人并没有错 ? ,只是我跟他们一样固执!

48d8b136ee4a33337bc5d103600d602d.png

这个函数是干什么的?

Array.reduce() 是 JavaScript 中的一个数组函数,是一个对数组中的每个元素按顺序执行一个提供的回调函数,并将它们累计为一个单一的返回值的方法。

下面是该函数的一个简单示例:

const value = [1,2,3,4].reduce((acc, cur) => {
  return acc + cur;
}, 0);


// value: 10

这个函数接收两个参数:

  1. callback:一个回调函数,即 reducer

  2. initialValue:累积值的初始值

回调函数接受 4 个可选参数:

  1. accumulator:累积值

  2. currentValue:你正在遍历的数组的当前项

  3. currentIndex:你正在遍历的数组的当前索引

  4. array:你正在遍历的整个数组

一个完整的签名看起来像这样:

const reducer = (accumulator, currentValue, currentIndex, array) = > {
   return accumulator;
}


const value = [...].reduce(reducer, 0)

8daf45c24c33f9f88fed2cdd87d20349.png

问题出在哪里?

在翻阅这些抱怨之后,一个普遍的抱怨是:Array.reduce()  太难阅读和理解了。

在审查代码、扫描新的代码库或阅读文档时,遇到 Array.reduce() 需要你停下来,花一会儿时间思考数组到底发生了什么。

因为,你可以使用另一种 Array 方法如 Array.forEach() 或者简单的 for 循环,以更易读的方式达到同样的结果。

虽然这些观点提的很好,但它们是错的!

4cd85c277ae747ea83ea68c8ef146825.png

我的理由

当我阅读这些评论时,我想到了一些事情。我认为这些观点背后的很多理由都非常有道理!但是,他们吐槽的焦点被引向了错误的方向。

我对此事的首要想法是,真正的问题并不在于方法签名和复杂性,而是在于开发者最大的敌人:命名问题。

实际上,我认为这个问题在争议中根深蒂固,以至于它以两种不同的方式显现出来!

04d8af938859bbee97adfb8118bcad6b.png

展示 A:它不应该被命名为 reduce

首先,这个方法被命名为 reduce。虽然在很多情况下这个方法名是有道理的。但 Array.reduce() 方法非常强大,它可以做的远不止将数组减少到一个单一的值。

考虑一下下面的函数使用方法:

const smallNumbers = [1,2,3,4,5];
const largeNumbers = smallNumbers.reduce((newArray, current) => {
  newArray.push(current ** 2);
  return newArray;
}, []);


// largeNumbers: [1,4,9,16,25]

在这种情况下,我们并没有减少初始数组的长度。我们在 转换 它!所以,这就是足够让人讨厌 Array.reduce() 的理由吗?我并不这么认为!

Array.prototype.transform = Array.prototype.reduce;

如果我们给数组的原型对象添加一个 transform 方法,这个方法和 reduce 方法是一样的,都是对数组的每个元素执行一个函数,并返回一个累积的结果,那么问题就瞬间解决了。

显然,这只是一个玩笑。一个完全解决问题的玩笑,但仍然只是一个玩笑。

c4d992c724e6cb796bed188f1036adea.png

展示 B:人们在命名参数时偷懒

你有多少次见过下面这样的循环:

const array = [...];
let crazyValue = 0;
for (let i = 0; i < array.length; i++) {
  for (let j = 0; j < i; j++) {
    crazyValue = i + j;
  }
}

i 和 j 代表什么?为什么这些单字符变量名这么常见,以至于看起来几乎是正常的?

同样(恶心)的问题存在于 Array.reduce() 的使用中。你会经常看到这样的代码:

const array = [...];
const crazyValue = array.reduce((acc, curr, i, arr) => {
 return acc + curr;
}, 0)

acc、curr、i 和 arr 是什么意思?我们可以通过更具描述性的变量名来解决这个令人困惑的问题:

const array = [...];
const crazyValue = array.reduce((total, currentValue, index, originalArray) => {
 return total + currentValue;
}, 0)

或者再进一步优化:

const array = [...];
const initialValue = 0;
const addValues = (total, currentValue, index, originalArray) => {
   return total + currentValue;
}


const crazyValue = array.reduce(addValues, initialValue)

这可能不是完美的解决方案,但它肯定使代码更容易阅读和理解。

a3073491b0d5a764a3a58fd7dfcacacb.png

你怎么看?

Array.reduce()  真有那么糟糕吗?我并不这么认为。如果你将 Array.reduce() 理解为一个不仅可以将数组累计为一个单一的值,还具有其他功能的强大的函数,就更容易理解了。

我看到的很多问题都是用户在命名上犯的错误。比如,用不恰当的变量名或函数名,导致代码难以理解或出现 bug。

对这个问题你怎么看?你同意我的看法吗?

a1962181da27922a940397c3fe6ed3f5.png

附加问题:

Array.prototype.transform = Array.prototype.reduce;
const add = (total, current) => total + current;
const initialValue = 0;
const sumOfNumbers = [1,2,3,4,5].transform(add, initialValue);

你赞成这么做吗?

推荐阅读:

▶iPhone 15 或推迟上市;谷歌软件工程师基本年薪达 71.8 万美元;Godot 4.1.1 发布|极客头条

“世界头号黑客” Kevin Mitnick 去世,59 年传奇人生落幕

无人能构想出人工智能的未来 | 对话伯克利顶级学者 Stuart Russell

027e39c3040d8026bf56491c604ca0b1.png

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695