在不使用返回值的情况下执行映射操作是否是反模式?

时间:2019-07-05 13:06:53

标签: javascript functional-programming mapping

让我们说我有一个列表,我想使用映射函数向其中添加一些值:

const arr = [1, 2, 3, 4, 5];
const anotherArr = [];

我使用功能性方法进行此操作:

arr.map((item) => anotherArr.push(item);

这是否是反模式/错误的逻辑-也就是说,不对任何东西使用映射操作返回值?有什么好的资源吗?

(我知道这种逻辑很愚蠢,我只能复制列表-这不是我要问的重点)

1 个答案:

答案 0 :(得分:3)

是的,这是一种反模式。 .map方法的用法很明确-您可以将一个数组的内容转换为另一个数组的内容。您可以通过提供一个表示每个元素之间关系的映射函数来做到这一点,例如,可以通过以下函数来表示将字母转换为字母在字母表中的位置:

function letterToPositionInAlphabet(letter) {
  return letter.toUpperCase().charCodeAt(0) - 64;
}

因此,通过此函数映射字母数组将为您提供一个数组,显示每个字母的位置:

function letterToPositionInAlphabet(letter) {
  return letter.toUpperCase().charCodeAt(0) - 64;
}

const letters = ["a", "b", "c"];

console.log(letters.map(letterToPositionInAlphabet));

映射操作是惯用的,是理解代码的一部分。如果您看到someArr.map(someFn)设置了期望值,那么就很容易了解正在发生的操作类型,而无需知道数组或函数的内容。当您看到letters.map(letterToPositionInAlphabet)时,要弄清意图是不重要的-获取某些字母的字母位置。

但是,将.map用作.forEach违反了预期的含义,可能会使阅读混淆。有这个

function playerToPlaceInRankList(player) {
   const position = lookupPlayerRank(player);
   positionsArr.push(position);
}

/* many lines later */

players.map(playerToPlaceInRankList);

/* more code */

看起来像执行映射的行也立即看起来错误,因为返回值被忽略了。要么不需要该行,要么必须查找playerToPlaceInRankList的操作才能发现此处实际发生的情况。仅阅读应直接的代码和自我记录的代码,这是不必要的精神负担。

使用其他方法(例如.filter.find.every.some等)也是如此。不要仅仅因为它们遍历数组而使用它们,如果您想要的不是他们打算做的。