一段JS的Array评测之旅(休闲娱乐划水伴侣)
前言
当清晨的第一缕阳光,映照在我脸庞。犹如一双饱含温情的手抚摸着抚摸着,我便起了床。雨水洗刷过的街道,弥漫着沁人心脾的清香。 街边早餐铺的油条在锅中滋滋发出声响,我知道这根热气腾腾新鲜出炉的油条,过一会儿将会去到下一个地方。我三两口就送它去了(就像B站美食up主徐大sao在重庆时的狠话二两面我两口就吃完了)我便来到了早晨的第一个打卡点,地铁站🚞。车厢内真是人山人海挨肩擦背一点都不夸张,有时停站耳边也会传来工作人员的呐喊声(挤嘛,这儿还可以qi一个)下了车也是人头攒动步履艰辛。在车厢里结伴同行的人很少,大家都习惯低着头看着手机这让我想起了一句话抬头看见梦想,低头却碰见了现实我也闭上了双眼开始陷入沉思🤔,JS的数组api中属于遍历的有很多,它们各司其职。但是真正的使用场景是什么?哪一个在场景中性能更高,更快?便有了下文。
有看面试相关的小伙伴可以浏览下好朋友正在火热筹划中的 面试汇总库💪
若文章中的解答有误,希望能够得到小伙伴们的指正与谅解。希望能和你来一场知识的碰撞。
在计算之前,我需要一个计算运行时间函数,和一个实验测试数组arr
function calcTime (func) {
let start = new Date().getTime(); //开始时间
func(); //执行待测函数
var end = new Date().getTime(); //结束时间
return (end - start)+ "ms"; //返回函数执行需要时间
}
let arr = [] // 创建一个我需要的测试数据
for(let i=0;i<1000000;i++) {
arr.push(i)
}
Array 遍历API
find()
find() 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
我现在有一个需求,从一个数组中,找出指定项。

// 使用find前
function foo(){
for(let i=0;i<arr.length;i++){
if(arr[i] === 50000) return;
}
}
//使用find后
function findFoo(){
arr.find( item => item === 50000)
}
calcTime(foo) // 16ms
calcTime(findFoo) // 1ms find更优
本次实验环境是在JSBin保证了环境相同,设备相同,情景相同,所有实验结果都会会根据你的电脑性能给出不同值。所以不要考虑绝对值,参考点是在相对值👆。
forEach,map
forEach() 方法对数组的每个元素执行一次提供的函数。
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
为了避免JSBin崩溃,本次arr长度为1w
function foo(){
for(let i=0;i<arr.length;i++){
for(let j=0;j<arr.length;j++){}
}
}
// 使用forEach
function foreachFoo(){
arr.forEach(()=>{
arr.forEach(()=>{})
})
}
// 使用map
function fooMap(){
arr.map(()=>{
arr.map(()=>{})
})
}
calcTime(foo) // 39ms
calcTime(foreachFoo) // 649ms
calcTime(foreachMap) // 699ms for()更优
filter
filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。本次arr长度10w

function foo(){
let newArr =[]
for(let i=0;i<arr.length;i++){
if(arr[i]>=50000){
newArr.push(arr[i])
}
}
}
// 使用filter
function filterFoo(){
letnewArr = arr.filter(item=> item>=50000 )
}
calcTime(foo) // 59ms
calcTime(filterFoo) // 4ms filter更优
reduce
reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
function foo(){
let sum = 0
for(let i=0;i<arr.length;i++){
sum = sum + arr[i]
}
}
// 使用reduce
function reduceFoo(){
arr.reduce((sum,item)=>sum +item)
}
calcTime(foo) // 57ms
calcTime(reduceFoo) // 4ms reduce更优
通过简单的几个对比,可以知道数组中创造filter,find,reduce都是有目的。还是俗话说的好,术业有专攻。我们作为开发者首先应该知道每个api的作用,然后考虑自己的业务场景选择最佳的方法。 举个🌰

以前的写法:
iconFliter(num){
if(num>0 && nun<=30){
return 'normal'
}
if(num>30 && nun<=100){
return 'orange'
}
if(num>100 && nun<=250){
return 'yellow'
}
if(num>250){
return 'red'
}
这样写并没有问题,但是我们可以仔细思考下,我们可以借用现有的数据结构(对象,数组)他们的特点来完成,如下
// 业务中独立的变量转化成数组和对象结构
let datas = [{time:30,color:'normal'},{time:100,color:'orange'},{time:250,color:'yellow'}]
// 再通过高效的api进行处理
function iconFilter(num,data) {
if (num<0) return
let selectData = data.find(item => num <= item.time)
return selectData ? selectData.color:'red'
}
只要多思考,代码肯定会越写越好。
数组总结
返回Boolean的方法
方法名 | 描述 |
---|---|
some | 检测数组元素中是否有元素符合指定条件 |
every | 检测数值元素的每个元素是否都符合条件。 |
includes | 判断一个数组是否包含一个指定的值。 |
修改原数组的方法(面试中经常被问起)
方法名 | 描述 |
---|---|
push | 向数组的末尾添加一个或更多元素,并返回新的长度 |
pop | 删除数组的最后一个元素并返回删除的元素 |
unshift | 向数组的开头添加一个或更多元素,并返回新的长度 |
shift | 删除并返回数组的第一个元素 |
reverse | 反转数组的元素顺序 |
splice | 从数组中添加或删除元素 |
sort | 对数组的元素进行排序 |
剩下的方法就是不改变原数组的方法
一道题
平时业务中经常会对后端小伙伴返回的数组对象进行处理,此时我需要将citizenship(国籍)为china的对象属性name换成chineseName,新增一个属性location值为Asian,国籍为america也要进行操作,你会怎么做?如下所示吗?平时你就是这种写的吗?
let datas = [{name:'张大娃',age:19,sex:'boy',citizenship:'china'},
{name:'张老二',age:35,sex:'boy',citizenship:'china'},
{name:'赵二娃',age:21,sex:'boy',citizenship:'china'},···]
datas.forEach(item=>{
if(item.citizenship === 'china'){
item.chineseName = item.name
item.location = 'Asian'
}else if (item.citizenship === 'America') {
item.americaName = item.name
item.location = 'northAmerica'
}
})
希望你能帮我优化一下上面的代码
马上就要打下班卡领取周末了,祝大家周末愉快天天开💓
转载自:https://juejin.cn/post/6844903888240246797