数组的方法之遍历篇

这篇文章详细介绍了JavaScript中四个重要的数组方法的自定义实现:_forEach()用于遍历数组并执行回调函数;_map()创建新数组,每个元素是原数组元素经过回调函数处理的结果;_filter()生成一个新数组,包含通过回调函数测试的元素;_reduce()将数组元素累计为单个返回值。这些方法的核心在于回调函数的应用和thisArg的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

forEach()

//Array.prototype.forEach()方法对每个元素执行一次提供的回调函数;

//第一个参数是我们提供的回调函数;

//第二个参数thisArg:回调函数中this指向,即如果我们想在回调函数中对非回调函数的作用域进行一些操作,那么就可以把操作的对象当成第二个参数传进去;

Array.prototype._forEach = function(fn,thisArg){

  if(typeof fn !== 'function') throw '参数必须为函数'

  if(!Array.isArray(this)) throw '只能对数组使用此方法'

  let arr = this

  for(let i = 0; i< arr.length; i++) {

    //就是在这里,使用call改变this指向,指向第二个参数;

    fn.call(thisArg, arr[i], i, arr)

  }

}

map()

//Array.prototype.map() 方法创建一个新数组,其结果是该数组中的每个元素调用一次提供的回调函数后的返回值。由此我们可以看出map()和forEach()最大的区别就是map()创建一个新数组,而forEach()是对原来数组的操作;

//两个参数和forEach()的参数一样;

Array.prototype._map = function(fn, thisArg) {

  if(typeof fn !== 'function') throw '参数必须为函数'

  if(!Array.isArray(this)) throw '只能对数组使用此方法'

  let arr = this

  //别忘了我们最终是要返回一个新的数组

  let newArr = []

  for(let i = 0; i < arr.length; i++) {

    //把每次调用回调函数fn的返回值push到新的数组

    newArr.push(fn.call(thisArg, arr[i], i, arr))

  }

  //最后返回这个新数组

  return newArr

}

filter()

//Array.prototype.filter()方法创建一个新数组,其包含通过给定函数测试的所有元素;注意调用这个方法会返回一个新数组,并且新数组中的元素是经过我们筛选的;

//两个参数和forEach()的参数一样;

Array.prototype._filter = function(fn, thisArg) {

  if(typeof fn !== 'function') throw '参数必须是回调函数'

  if(!Array.isArray(this)) throw '只能为数组使用此方法'

  let arr = this

  let newArr = []

  for(let i = 0; i< arr.length; i++) {

    if(fn.call(thisArg, arr[i], i, arr)){

      newArr.push(arr[i])

    }

  }

  return newArr

}

reduce()

//Array.prototype.reduce()方法对数组中的每一个元素执行一个我们提供的回调函数(reducer函数,升序执行),并将结果汇总为单个返回值;reduce()方法和上面三个都不同,它返回的不是数组而是单个返回值

//第一个参数是回调函数

//第二个参数是初始值,即累加的时候需要有一个起始值;

Array.prototype._reduce = function(fn, initialV) {

  if(typeof fn !== 'function') throw '参数必须是回调函数'

  if(!Array.isArray(this)) throw'只能为数组使用此方法'

  //给个空数组又不给初始值,那累加个什么。。。

  if(!this.length && ! initialV) throw '请传入初始值或非空对象使用此方法'

  let arr = this

  let result = initialV || arr[0]

  for(let i =0; i< arr.length; i++) {

    //如果提供了初始值,则累加的起始索引为0,否则就把第一个元素作为累加的基础,再从第二个元素开始加;即如果没提供初始值,我们就跳过本次循环继续下次循环;

    if(!initialV && i ===0) continue

    //通过递归的方式,把这次的累加的结果作为下次累加的基础

    result = fn( result, arr[i], i, this)

  }

  return result

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值