面试题答案
一键面试操作顺序的性能优化
- 优先执行filter:filter方法会创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。在一个非常大的数组上,先进行filter操作可以显著减少后续操作的数据量。例如,如果原始数组有10万个元素,filter可能将其减少到1万个,那么后续的map和reduce操作只需要处理这1万个元素,大大降低了计算量。
- 接着执行map:map方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。由于经过filter后数据量已经减少,map操作处理的数据量也相应减少,从而提高效率。
- 最后执行reduce:reduce方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。此时处理的数据量已经是经过filter和map处理后的较小数据量,性能会更好。
JavaScript引擎底层处理机制
- 内存管理:
- map:创建一个新数组,新数组的长度与原数组相同,每个元素是原数组元素经过映射函数处理后的结果。原数组不会被修改,这意味着需要额外的内存空间来存储新数组。
- filter:同样创建一个新数组,新数组的长度小于或等于原数组,只包含通过测试的元素。原数组也不会被修改,需要额外内存存储筛选后的新数组。
- reduce:不会创建新数组,它在遍历数组过程中不断更新累加器的值,最后返回单个值。相对map和filter,reduce对内存的额外需求较小。
- 遍历机制:
- map:遍历原数组的每一个元素,对每个元素执行传入的映射函数,并将返回值存入新数组。
- filter:遍历原数组,对每个元素执行传入的测试函数,若函数返回true,则将该元素存入新数组。
- reduce:从数组的第一个元素开始(或者可以指定初始值开始),依次对每个元素执行reducer函数,将上一次的计算结果(或者初始值)与当前元素作为参数传入reducer函数,不断更新累加器的值。
优化后的代码示例
const largeArray = Array.from({ length: 100000 }, (_, i) => i + 1);
// 优化后的顺序
const result = largeArray
.filter(num => num % 2 === 0) // 过滤出偶数
.map(num => num * 2) // 将偶数翻倍
.reduce((acc, num) => acc + num, 0); // 累加翻倍后的偶数
console.log(result);
在上述代码中,先通过filter筛选出偶数,减少了数据量,再通过map对筛选后的偶数进行翻倍操作,最后通过reduce累加翻倍后的偶数,这种操作顺序可以有效提高性能。