数组几种遍历方式+源码实现

153 阅读3分钟

以前总是忘记数组的各种方法,这次重要总结几种遍历方法。先看MDN,再看相关文章,写笔记。小菜鸡,终于写出这篇文章。

1.forEach

基本用法

语法:arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

callback:为数组每个元素执行函数,可选一到三个参数(currentValue:当前值,index:当前索引值,array:正在操作的数组)

thisArg:回调函数的this值

forEach() 被调用时,不会改变原数组

返回值:undefined

let arr=[1,2,6] 
arr.forEach(function(e){    
console.log(e) }) // 1 // 2 // 6

手写代码for+call,用call是为了绑定this

Array.prototype.myForEach = function (callbackFn) {
    //判断this是否合法
    if (this === null || this === undefined) {
        throw new TypeError('myForEach of null')
    }
    //判断callbackFn是否合法
    if (typeof callbackFn !== 'function')
        throw new TypeError(callbackFn + 'is not function')

    //取到数组对象和传入的this值(通过arguments[1])浏览器是window,node环境时globalThis
    var _arr = this, thisArg = arguments[1] || globalThis
    //开始执行
    for (let i = 0; i < _arr.length; i++) {
        callbackFn.call(thisArg, _arr[i], i, _arr)

    }

}

2.reduce

基本用法

详见Array.prototype.reduce() - JavaScript | MDN (mozilla.org)

语法:reduce(function(previousValue, currentValue, currentIndex, array) { /* ... */ }, initialValue)

callback函数,4个参数(previousValue:上次调用callbackFn时的返回值,currentValue:数组正在处理的元素,currentIndex:数组中正在处理的元素的索引值,arry:用于遍历的数组)

initialValue,作为第一次调用 callback 函数时参数 previousValue 的值。若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;否则 

previousValue 将使用数组第一个元素,而 currentValue 将使用数组第二个元素。

返回值:数组遍历后结果

let sum=[0,2,22,3]
let total=sum.reduce(function(pre,cur){
    return pre+cur
},0)
console.log(total)

手写代码

reduce(function(previousValue, currentValue, currentIndex, array) { /* ... */ }, initialValue)

callbackFn(accumulator,_arr[i],i,_arr),看看

Array.prototype.myReduce=function(callbackFn){
    //保存数组对象和定义一个累加器(如果传入了初始值arguments[1])
    var _arr=this,accumulator=arguments[1];
    //遍历索引值
    var i=0;
    //判断是否传入初始值
    if(accumulator===undefined){
        //初始第值是数组一个元素
        accumulator=_arr[i]
        i++;
    }
    for ( ;i<_arr.length;i++) {
        console.log(accumulator)
        //收集,callbackFn,累计值,当前值,当前索引,当前数组
      accumulator=callbackFn(accumulator,_arr[i],i,_arr)

    }
    return accumulator

}
let sum=[0,2,22,3]
let total=sum.myReduce(function(pre,cur){

    return pre+cur
},0)
console.log(total)//27

3.map

基本用法

语法:var new_array=arr.map(function callback(currentValue[,index[,array]]){},[,thisArg])

callback:回调函数,currentValue:当前遍历的值,index:当前元素的索引值,arrary当前数组

thisArg:执行callback函数时被用作this

返回值:一个新的数组

let arr=[2,5,1]
let double=arr.map(function(num){
    //console.log(...arguments)
    return num*2
})
console.log(double)

手写代码

Array.prototype.myMap=function(callbackFn){
   var _arr=this,thisArg=arguments[1]||window;
   //返回的数组
   var res=[]
    for (let i = 0; i < _arr.length; i++) {
        res.push(callbackFn.call(thisArg,_arr[i],i,_arr))

    }
    return res
}
let arr=[2,5,1]
let double=arr.myMap(function(e){
    console.log(this)
    // console.log(arguments)//_arr[i],i,_arr
    // console.log(e)
    return e*2
})

4.filter

基本用法

语法:var= newArray=arr.filter(callback(element [,index [,array]) [,thisArg])

callback:要测试数组的每个元素的函数,3个参数(element:当前遍历的值,index:当前元素的索引值,arrary当前数组)

thisArg:绑定的this

返回值:创建一个新的数组,是要通过测试函数的元素

let arr = [1, 2, 3]

let newArr = arr.filter(function (e) {
    return e > 1
})
console.log(newArr)//2,3

手写代码

Array.prototype.myFilter = function (callbackFn) {
    var _arr = this, thisArg = arguments[1] || globalThis;
    //返回的数组
    var res = []
    for (let i = 0; i < _arr.length; i++) {
        //测试函数通过
        if (callbackFn.call(thisArg, _arr[i], i, _arr)) {
            res.push(_arr[i])
        }
    }
    return res
}

let arr = [1, 2, 3]
let newArr = arr.myFilter(function (e) {
    return e > 1
})
console.log(newArr)//2,3

5.every

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值

基本用法

语法:arr.every(callback(element[, index[, array]])[, thisArg])

callback:要测试数组的每个元素的函数,3个参数(element:当前遍历的值,index:当前元素的索引值,arrary当前数组)

thisArg:绑定的this

返回值:一个布尔值

let arr = [1, 2, 3]
var bol=arr.every(function(e){
  return  e>1
})
console.log(bol)//false

手写代码

Array.prototype.myEvery=function(callbackFn){
    var _arr = this, thisArg = arguments[1] || globalThis;
    var bol=true;
    for (let i = 0; i < _arr.length; i++) {
      if(!callbackFn.call(thisArg,_arr[i],i,_arr))
        bol=false
    }
    return bol
}

let arr = [1, 2, 3]
var bol=arr.myEvery(function(e){
  return  e>1
})
console.log(bol)//false

6.some

some() 方法测试一个数组内只要一个元素是否都能通过某个指定函数的测试,它就通过了。

基本用法

语法:arr.some(callback(element[, index[, array]])[, thisArg])

callback:要测试数组的每个元素的函数,3个参数(element:当前遍历的值,index:当前元素的索引值,arrary当前数组)

thisArg:绑定的this

返回值:一个布尔值

 let arr = [1, 2, 3]
var bol=arr.some(function(e){
  return  e>1
})
console.log(bol)//true

手写代码

Array.prototype.mySome=function(callbackFn){
    var _arr = this, thisArg = arguments[1] || globalThis;
    var bol=false;
    for (let i = 0; i < _arr.length; i++) {
      if(callbackFn.call(thisArg,_arr[i],i,_arr))
        bol=true
    }
    return bol
}

let arr = [1, 2, 3]
var bol=arr.mySome(function(e){
  return  e>1
})
console.log(bol)//true

7.find

find() 方法测试一个数组内只要一个元素是否都能通过某个指定函数的测试,如果就返回该值且是第一个满足该条件,没有就返回undefined。

基本用法

语法:arr.some(callback(element[, index[, array]])[, thisArg])

callback:要测试数组的每个元素的函数,3个参数(element:当前遍历的值,index:当前元素的索引值,arrary当前数组)

thisArg:绑定的this

返回值:如果有符合要求的元素且是第一个满足条件就返回该值,没有就返回undefined

let arr = [1, 2, 3]
var item=arr.find(function(e){
  return  e>1
})
console.log(item)//2

手写代码

Array.prototype.myFind=function(callbackFn){
    var _arr = this, thisArg = arguments[1] || globalThis;
    for (let i = 0; i < _arr.length; i++) {
      if(callbackFn.call(thisArg,_arr[i],i,_arr))
       return _arr[i]
    }
    return undefined
}
let arr = [1, 2, 3]
var item=arr.myFind(function(e){
  return  e>1
})
console.log(item)//2

let arr=[2,2,3,4]
let pos=arr.indexOf(2,1)
console.log(pos)

8.indexOf

基本用法

语法:arr.indexOf(searchElement[,fromIndex])

searchElement:要查找的元素

fromIndex:默认为0

如果为负值+length,

大于数组长度找不到,直接返回-1

返回值:首次找到的位置,若没有返回-1


let arr=[2,2,3,4]
let pos=arr.indexOf(2,1)
console.log(pos)

手写代码

Array.prototype.myIndexof=function(element,index){
    var _arr=this
    if(index!==undefined){
        if(index>_arr.length||this.length<1){
            return -1;
        }else if(index<0){
            index=index+_arr.length
        }
    }else{
        index=0
    }
    for (let i = index; i < _arr.length; i++){
     
      if(_arr[i]===element){
        return i;
      }
    }
}

let arr=[2,2,3,4]
let pos=arr.myIndexof(2,1)
console.log(pos)