通过解构或forEach减少 - 迭代和Airbnb JavaScript风格指南

时间:2017-05-18 11:01:01

标签: javascript iterator reduce airbnb eslint-config-airbnb

我有一个对象:

things = {
  table: 'red',
  chair: 'green'
}

遵循Airbnb的JavaScript样式指南,我想创建一个复制此对象的函数,将对象的所有键设置为蓝色。

我的2个选项似乎是:

1使用reduce

function alwaysBlue(things) {
  return Object.keys(things)
    .reduce((acc, thing) => ({ ...acc, [thing]: 'blue' }), {})
}

2使用forEach

function alwaysBlue(things) {
  const blueThings = {}
  Object.keys(things)
    .forEach(thing => (blueThings[thing] = 'blue'))
  return blueThings
}

(1)对每次迭代的解构似乎都很昂贵,但如果我将no-param-reassign考虑​​进去,我就无法在每次迭代时附加到累加器

然而,根据https://github.com/airbnb/javascript#iterators--nope,应该避免forEach(2)支持map()/ every()/ filter()/ find()/ findIndex()/ reduce()/ some()

如果我要遵守Airbnb的JavaScript样式指南,那么首选哪种方法 - 还是我还缺少另一种方法?

5 个答案:

答案 0 :(得分:2)

我说一般指导原则是您可以遵守您选择的编码惯例,除非它们强迫您编写对性能有负面影响的实施足够大以至于。如果是这样,那么你将不得不做出必要的牺牲编码标准,以便编写一个表现良好的实现。

我不知道你的真实世界数据是什么,但我敢打赌#1会做得很好,如果没有,那么#2很可能是一个很好的妥协。指南并没有说forEach 不好,它只是最好

答案 1 :(得分:1)

github issue上回答(这应该是您在本指南中提出问题的第一个也是唯一的一个地方):

由于这是无效的语法,我假设你的对象是:

   things = {
      table: 'red',
      chair: 'green'
    }

使用reduce的第一个示例是正确的。 “看起来很昂贵”是你不应该担心的 - 性能是最不重要的,只有在代码正确,干净,经过测试,分析后才会关注。

只有当它最终成为必要时(通过完全基准测试你的应用程序而不是像jsperf这样的微基准测试),然后你将使用你的forEach方法,然后如果它仍然是必要的,你将它转移到一个for循环。

答案 2 :(得分:0)

如果您要使用lodash之类的第三方工具,可以使用mapValues

_.mapValues(things, () => 'blue');

答案 3 :(得分:0)

您可以使用Object.assign,它不会创建新对象,而只是将项目附加到累加器。性能更好,并且坚持风格指南。

Object.keys(things)
    .reduce((acc, thing) => Object.assign(acc, {[thing]: 'blue' }), {})

答案 4 :(得分:-2)

只需使用一个简单的循环:

function alwaysBlue(things) {
  const blueThings = {}
  for (const key in things) // or `for (const key of Object.keys(things))`
    blueThings[key] = 'blue'
  return blueThings
}

这些迭代方法仅适用于数组,我们不会在这里处理。