这是一篇关于最近出现的一个流行模式的短文:一起使用数组reduce 方法和传播操作符(...)。让我们看一个快速的例子,我们一起使用它们来交换一个对象的键和值。
const obj = { a: 1, b: 2, c: 3 };
const flipped = Object.entries(obj).reduce(
(all, [key, val]) => ({
...all,
[val]: key,
}),
{}
);
console.log(flipped);
// { '1': 'a', '2': 'b', '3': 'c' }
很酷,对吗?
问题:对于大型数组来说,同时使用Reduce和Spread是非常低效的。
如果你研究一下上面的例子,你就会发现,每次我们执行传递给reduce 方法的函数时,我们都会创建一个all 对象的浅层拷贝。这对小数组来说可能不是什么大问题,但很快就会成为一个性能瓶颈。让我们创建一个真正的大数组,测试一下我们的reduce/spread组合的表现。
const largeArr = new Array(100000).fill(1).map((_, i) => i);
// [0, 1, 2, 3, ..., 99999]
console.time('try 1');
const obj1 = largeArr.reduce(
(all, el) => ({
...all,
[el]: el,
}),
{}
);
console.timeEnd('try 1');
// try 1: 20985.787ms
呀,这花了21秒那么,我们该怎么做呢?
普通的老式循环来拯救
在很多情况下,事实证明,一个普通的老式for 循环或forEach 方法就能完成任务。在下面的例子中,我们只用了~5毫秒就完成了与上面的代码相同的任务。
console.time('try 2');
const obj2 = {};
for (let i = 0; i < largeArr.length; i++) {
obj2[largeArr[i]] = largeArr[i];
}
console.timeEnd('try 2');
// try 2: 4.620ms
结论
在一起之前,请仔细考虑一下!如果你要处理小的数组,你可能会没事,但当你的数组变大时,肯定会对性能产生影响。