重写数组扩展方法-forEach

190 阅读2分钟

如何深刻了解数组的扩展方法? 最简单的办法就是重写!

关于数组扩展方法forEach的重写,下边是全部代码

Array.prototype.myForEach=function (cb){
    const _arg=this
    const _len=this.length
    const _arg2=arguments[1] || window

    for(let i=0;i<_len;i++){
        cb.apply(_arg2,[_arg[i],i,_arg])
    }
}

接下来,我将一一介绍如何重写forEach,重写forEach的前提是充分的了解forEach这个API的设计风格以及用法。

Array.prototype.forEach((item,index,array)=>{
    
},obj)

以上是forEach所接收的参数,forEach共接收两个参数,第一个参数为回调函数(callback),此函数可接收三个参数,分别是item(需要遍历的元素本身)、index(需要遍历元素的索引)、array(需要遍历的数组),在函数体内可以对这三个参数进行使用,第二个参数则为修改this指针的对象,当第二个参数传递的为一个对象时,那么第一次参数的函数体内的this指针就指向这个对象。

接下来,根据我们对forEach的了解,重写forEach,首先,我们在Array的原型(prototype)上绑定重写的myForEach,即:

Array.prototype.myForEach=function (){}

根据分析,forEach接收两个参数,则myForEach也接收两个参数,我们先写第一个参数callback,因为第二个参数可传可不传,所以第二个参数我们不能写死,第二个参数我们使用 arguments[1] 去接收,即:

Array.prototype.myForEach=function (cb){}

在函数体内,首先要搞清楚,函数体内的this指针指向的是谁,在Javascript中,谁调用的这个函数,则这个函数体内的this就指向谁,所以我们需要使用变量去维护this指针。

forEach是遍历每一个元素,所以也需要用变量去维护数组的长度,即:

const _arg=this
const _len=this.length

因为forEach的第二个参数不是固定的传值,所以第二个参数如果不传,默认为window,如果传值,则用 arguments[1] 去获取。即:

const _arg2=arguments[1] || window

最后用for循环遍历数组,即:

for(let i=0;i<_len;i++){
    cb.apply(_arg2,[_arg[i],i,_arg])
}

cb为第一个传入的回调函数参数,用apply方法调用cb回调函数(apply方法第一个参数为this指针,第二个参数为数组,数组中为函数体所需的参数),根据之前的分析,apply的第一个参数为_arg2(默认为window,如果传入forEach的第二个参数,this则指向forEach的第二个参数),回调函数中需要三个传参,item、index、array,所以与之对应的为 _arg[i] , i , _arg。

因为forEach没有返回值,所以不用return返回值。