0

我有一个对象:

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

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

我的两个选择似乎是:

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/,应避免使用 forEach (2),而应使用 map()/every()/filter()/find()/findIndex()/reduce()/some() airbnb/javascript#iterators--不

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

4

5 回答 5

2

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

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

于 2017-05-18T14:22:25.373 回答
1

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


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

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

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

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

于 2017-05-18T15:41:12.803 回答
0

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

Object.keys(things)
    .reduce((acc, thing) => Object.assign(acc, {[thing]: 'blue' }), {})
于 2018-06-13T17:55:49.087 回答
0

如果您准备使用像lodash这样的第三方工具,您可以使用mapValues

_.mapValues(things, () => 'blue');
于 2017-05-18T15:49:14.580 回答
-2

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

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

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

于 2017-05-18T13:33:57.470 回答