【问题标题】:Reduce with deconstruction or forEach - Iteration and Airbnb JavaScript Style Guide使用解构或 forEach 减少 - 迭代和 Airbnb JavaScript 样式指南
【发布时间】:2017-10-18 03:51:32
【问题描述】:

我有一个对象:

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 样式指南,那么哪种方法是首选方法 - 还是我缺少另一种方法?

【问题讨论】:

  • 那个对象有语法错误。请修复它。

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


【解决方案1】:

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

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

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

【讨论】:

  • 请解释这有什么问题或它如何不符合风格指南
  • 我没有投反对票,但他们特别提到必须避免使用 for in 或 for of。
  • @plalx 风格指南说“更喜欢”,而不是“必须避免”。 for inObject.keys(…).forEach(…) 做的事情完全一样,但是更简单、更易读、更快,并且更明显地表明身体是用于突变的。这并不重要,因为alwaysBlue 整体上仍然是纯粹的。但是,是的,当一个人不关心二次复杂度并且可以使用实验语法时,纯reduce 解决方案就是要走的路。
  • 我没有投反对票,但是 for..in 在随附的 eslint 设置中被标记为受限语法:github.com/airbnb/javascript/blob/master/packages/… "message: 'for..in 循环遍历整个原型链,其中几乎从来都不是你想要的。使用 Object.{keys,values,entries} 并遍历结果数组。',"
  • 上面到 11.1 的链接还声明“不要使用迭代器...使用... Object.keys() / Object.values() / Object.entries() 来生成数组,这样你可以迭代对象。”
【解决方案2】:

我想说,一般准则是您可以遵守您选择的编码约定,除非它们强迫您编写对性能产生负面影响的实现足以考虑。如果是这种情况,那么您将不得不牺牲编码标准,以编写一个性能足够好的实现。

我不知道您的真实数据是什么,但我敢打赌 #1 会做得很好,如果不是,那么 #2 很可能是一个很好的折衷方案。指南没有说forEach 不好,它只是不是最好的

【讨论】:

    【解决方案3】:

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


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

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

    你的第一个例子是reduce,是正确的。 “看起来很昂贵”是您不应该担心的事情 - 性能是最不重要的事情,只有在代码正确、干净、经过测试、配置后才需要关注。

    仅当它最终是必要的(通过对您的应用程序进行全面基准测试来确定,而不是通过像 jsperf 这样的微基准测试来确定),然后您将使用您的 forEach 方法,然后如果仍然有必要,您将其转移到for 循环。

    【讨论】:

      【解决方案4】:

      如果您准备使用lodash 等第三方工具,您可以使用mapValues

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 2018-01-22
          • 1970-01-01
          • 2020-12-04
          • 2020-07-20
          • 1970-01-01
          • 2016-08-23
          • 2023-01-23
          • 2011-02-27
          • 2019-12-12
          相关资源
          最近更新 更多