js常用的ES5数组方法,使用案例详解.

ES5常用遍历数组方法

forEach

最基础的遍历方法,循环数组每一项,参数(指function的参数)包含每一项,每一项索引,数组本身.

  let arr = [1, 3, 5, 7, 9]
  arr.forEach((item, index, array) => {
    console.log(item, index, array);
  })
  //输出结果
  //1 0 [1, 3, 5, 7, 9]
  //3 1 [1, 3, 5, 7, 9]
  //5 2 [1, 3, 5, 7, 9]
  //7 3 [1, 3, 5, 7, 9]
  //9 4 [1, 3, 5, 7, 9]

forEach没有返回值,并且不能改变数组本身

  let arr = [1, 3, 5, 7]
  arr.forEach((item, index, array) => {
    item = item * 2
  })
  console.log(arr)
  //输出 [1, 3, 5, 7]  并没有改变数组本身
  let newArr = arr.forEach((item, index, array) => { })
  console.log(newArr);
  //输出 undefined foreach没有返回值

有人一定有疑惑,平时工作都是直接使用forEach来改变原数组内容的,例如后端返回一个数组,要根据数组的value来决定是true/fasle

  arr = [
    { id: 1, name: 'a', value: 0 },
    { id: 2, name: 'b', value: 0 },
    { id: 3, name: 'c', value: 1 }
  ]
  //处理数组 value 1处理为true 0处理为false
  arr.forEach(item => {
    item.value = item.value == 1 ? true : false
  })
  console.log(arr);
  //输出结果
  // [
  //   { id: 1, name: 'a', value: false },
  //   { id: 2, name: 'b', value: false },
  //   { id: 3, name: 'c', value: true }
  // ]

arr确实被成功修改了,每一项的value被替换成了布尔值,那forEach不能修改数组本身是不是错的呢? 并不是,在看下面例子

  arr = [
    { id: 1, name: 'a', value: 0 },
    { id: 2, name: 'b', value: 0 },
    { id: 3, name: 'c', value: 1 }
  ]
  arr.forEach(item => {
    item = item.value == 1 ? true : false
  })
  console.log(arr);
  //输出结果
  // [
  //   { id: 1, name: 'a', value: 0 },
  //   { id: 2, name: 'b', value: 0 },
  //   { id: 3, name: 'c', value: 1 }
  // ]

同样的操作,这次数组并没有发生变化,两次的区别是什么?第一次我们修改的是数组每项对象的一个值,而第二次修改的是每项对象的整体.我们知道对象属于是引用数据类型,可以理解为一个指针,它指向一个地址,而我们修改它内部的值等同于修改它指向地址里的内容.不算修改数组本身,而我们修改对象整体等于修改了数组每项指针地址,这就是等于修改数组本身,所以不会成功.

常用场景:需要对数组的每项数据进行操作

map

映射,和foreach功能基本类似,参数相同,不修改原始数组,有区别的是它有返回值

  let arr = [1, 3, 5, 7]
  let newArr = arr.map(item => {
    return item + 1
  })
  console.log(newArr);
  //输出结果 newArr接收到了返回值
  // [2, 4, 6, 8]

注意的是,map中要使用return,不写return 会返回undefined.
有人就不服了,我不写return也是对的,咋回事?

  let arr = [1, 3, 5, 7]
  let newArr = arr.map(item => item + 1)
  console.log(newArr);
  //输出结果
  // [2, 4, 6, 8]

上面代码确实不写return,也出结果了,咋回事?
我偷偷告诉你,箭头函数中如果是很简单的代码,将代码写在一行,并且去掉花括号,等于写了return,算是语法糖吧~

()=>{
return XXXX
}
()=> XXXX
//这两种写法是一样的

讲的这么细 关注我一下不过分吧😉

常用场景:需要一个新的数组,新数组的每项都与旧数组存在一定的关系。如果你并不需要一个新数组,选择使用map是违背逻辑的。

find / findIndex

find会找到数组符合项(第一个符合项),并返回该项,参数同上.
findIndex会找到数组符合项(第一个符合项),并返回该项索引,参数同上.

  let arr = [1,3,5,7]
  let n = arr.find((item, index) => {
    console.log('执行了');
    return item > 1
  })
  console.log(n);
  //输出结果
  //执行了*2
  //3
  let t=arr.find((item, index) => {
    return item < 1
  })
  console.log(t);
  //输出 undefined
  
  let a = arr.findIndex((item, index) => {
    console.log('执行了');
    return item > 1
  })
  console.log(a);
  //输出结果
  //执行了*2
  //1
  let b=arr.findIndex((item, index) => {
    return item < 1
  })
  console.log(b);
  //输出 -1

1.循环里的打印只打印了两次,说明find在找到符合条件项之后,就不在继续进行,大大减少了性能损耗.

2.find在找不到符合项的情况,会返回undefined

3.findIndex找不到符合项的情况下.会返回 -1

4.同需求下用find/findIndex比用foreach+if判断,性能会有提高

常用场景:根据后台返回数据,找到默认回显/选择项

filter

找到所有符合项,并返回一个数组,不会改变原数组,参数同上

  let arr = [1,3,5,7]
  let newArr = arr.filter((item, index) => {
    return item > 1
  })
  console.log(newArr);
  //输出结果 [3, 5, 7]
  let newArr2=arr.filter((item, index) => {
    return item < 1
  })
  console.log(newArr2);
  //输出 []

在功能上与map些许类似,都返回一个新数组.但区别与map返回的新数组项数一定与旧数组相同,而filter返回的新数组项数不一定等于旧数组.

附一个使用filter去重案例

  let arr = [1, 3, 5, 7, 7, 7, 7, 7, 7]
  let newArr = arr.filter((item, index, self) => {
    return self.indexOf(item) === index
  })
  console.log(newArr);
  // [1, 3, 5, 7]

常用场景:从后端返回数据结果中筛选出符合条件项,并以数组形式展现

some / every

这一对的返回结果都是布尔值,类似与&&和||的关系

some是只要有一个满足项,就返回true而every则是所有项满足条件才会返回true

记忆方法 :some有真即为真,every一假全为假.

  let arr = [
    { name: 'a', value: true },
    { name: 'b', value: false },
    { name: 'c', value: true },
  ]
  let res = arr.some(item => item.value)
  console.log(res) //输出 true
  let res1 = arr.every(item => item.value)
  console.log(res1) //输出 false

结合案列分析,使用some时因为原数组中两个符合条件的,所以是有真即为真,返回结果是true.使用every时,存在一个不符合的,一假全为假,返回false,全为假指的是已经有一项不满足了不用继续看了,结果肯定是假,并不是说每一项都不符合

以上所有方法在数组为空时都不会执行,都不会改变原数组,并且参数都相同

reduce

这个写电商业务的经常用,常用来写购物车累计价格.

它的参数与以上其它方法多一个,第一个参数是初始值,后三个参数同上.

  let arr = [1,2,3,4]
  let count = arr.reduce((pre,item,index,array)=>{
    console.log(pre,item,index,array);
    return pre+item
  },100)
  //输出结果
  // 100 1 0 [1,2,3,4]
  // 101 2 1 [1,2,3,4]
  // 103 3 2 [1,2,3,4]
  // 106 4 3 [1,2,3,4]
  console.log('共计',count);
  //共计 110

第一个形参是初始值,100就是我们设置的初始值.运行过程是首先先获取初始值(这里是100),然后用100累加(100是我们是设置的,所以累加从数组第一项开始),100+1=101,101将作为下次循环的初始值,第二次循环,初始值101(上一次运算得到的),累加,101+2=103,103将作为下次结果.

如果不设置初始值,将用数组第一项作为初始值.

  let arr = [1,2,3,4]
  let count = arr.reduce((pre,item,index,array)=>{
    console.log(pre,item,index,array);
    return pre+item
  })
  //输出结果
  // 1 2 1 [1,2,3,4]
  // 3 3 2 [1,2,3,4]
  // 6 4 3 [1,2,3,4]
  console.log('共计',count);
  //共计 10

这里我们没有设置初始值,所以初始值取了第一项,进行累加的时候也不会加第一项了,是从第二项开始,首先获取初始值(没有设置,所以用数组第一项),开始累加因为第一项当默认值了,所以从第二项开始累加,初始值1+第二项2=3,3将作为下一次循环的初始值,到二次循环,初始值3+第三项3=6作为下次循环初始值

再演示一个实际案例,计算购物车中的物品价格

  let arr = [
    { name: '苹果', price: 5, num: 2 },
    { name: '香蕉', price: 3, num: 1 },
    { name: '橘子', price: 2, num: 4 },
  ]
  let count = arr.reduce((pre, item, index, array) => {
    console.log(pre, item);
    return pre + item.price*item.num 
  }, 0)
  //输出结果
  // 1 2 1 [1,2,3,4]
  // 3 3 2 [1,2,3,4]
  // 6 4 3 [1,2,3,4]
  console.log('共计',count);
  // 共计 21
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白云苍狗い

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值