重写数组扩展方法-map

405 阅读2分钟

如何深入了解Javascript中的数组扩展方法-Map方法呢?最简单的办法就是重写!

下面是重写map方法的所有代码

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


    for(let i=0;i<_len;i++){
        const _item=deepClone(_arg[i])
        tar.push(cb.apply(_arg2,[_item,i,_arg]))
    }
    return tar

}

其中用到的深拷贝(deepClone方法),关于手写深拷贝可以参考这篇文章

重写数组方法的前提就是深刻了解此方法的用法以及特性,下面我将剖析map方法的用法。

数组的map方法共接收两个参数,第一个参数为回调函数(callback),第二个参数为改变第一个参数(回调函数)中的this指针,也就是回调函数中的this指针将指向第二个参数(第二个参数可传可不传)。具体代码如下:

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

其中第一个参数(回调函数)接收三个参数,分别是,item(当前遍历的元素)、index(当前遍历元素的索引值)、array(当前遍历的数组)。

map方法与forEach方法在返回值上的不同点就是,map方法会返回一个新的数组,而forEach方法则不会,所以,在重写map方法的时候一定要注意要 return 返回值。

在重写map方法之前,需要明白,在Javascript中,函数中的this指针的指向取决于谁调用这个函数,当取消严格模式时,函数的this指向默认为window,例如,假如一个函数fn,如果直接调用fn(),那么fn的this指针就指向window(未开启严格模式),即fn.call(window,...arg)。

明白了this指针指向问题,就可以开始重写map方法了,因为map方法是遍历数组中的每一个元素,所以我们需要用变量去维护this指针以及数组的长度,又因为map方法的第二个参数可传可不传,所以第二个参数不能写死,用 argument[1] 去接收(默认值为window)。于是就有了以下的代码:

const _arg=this;
const _len=this.length;
const _arg2= arguments[1] || window;

然后用for循环去遍历数组,遍历数组时,用cb.apply()方法去调用cb函数(回调函数),又因为map方法有返回值,所以我们传入cb.apply()方法中的当前元素需要深拷贝(item元素),且,需要一个返回的数组,返回数组也用变量去维护,即:

const tar =[]
const _item=deepClone(_arg[i])
tar.push(cb.apply(_arg2,[_item,i,_arg]))

最后一定不要忘记 return 出 经过遍历的数组(tar)!