我有一个对象:
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样式指南,那么首选哪种方法 - 还是我还缺少另一种方法?
答案 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
}
这些迭代方法仅适用于数组,我们不会在这里处理。