手写数组方法(一):map

601 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

大家在日常开发中,用的最多的数组操作大概就是map了,咱们今天就来掰扯掰扯map

map

参数

array.map(function(item,index,arr), ins)

参数1:回调函数(必需)

参数2:提供给回调函数的this指针(可选)

let ins = {a: 1};
let array = [1, 2, 3];
array.map(function(item, index, arr) {
    console.log(item, index, arr); 
    console.log(this);
}, ins);

d3173a3c52aa777ed100aa3c2a138ee.png

回调函数的参数:

第一个参数是当前遍历的数组项,

第二个参数是当前项的下标,

第三个参数是原数组。

注意

如果map函数的第二个参数不传,则回调函数的this为全局对象:

f89fcabd2785c5d28450371cd5e7556.png

箭头函数

由于箭头函数没有自己的this指针,所以第二个参数无效: 9d85fdf23295658cf72997ada32b479.png

遍历数组

map的遍历功能想必大家是相当熟悉了:

let arr = [1, 2, 3];
arr.map(x => {
    console.log(x);
});

控制台会依次输出1,2,3

返回值

我们将数组的每个元素都放大2倍:

let arr = [1, 2, 3];
let newArr = arr.map(x => x * 2);
console.log(newArr); // [2, 4, 6]
console.log(arr); // [1, 2, 3]

可以看到arr.map返回了一个新数组,并且值变为了原来的2倍。那如果我们不return 东西出来会怎么样?

let arr = [1, 2, 3];
let newArr = arr.map(x => {
    console.log(x);
});
console.log(newArr); // [undefined, undefined, undefined]
console.log(arr); // [1, 2, 3]

改变数组

重新赋值

所以数组的map操作不会改变原数组,那用map怎么改变原数组呢,将map变形后的数组重新赋值给原数组就好了:

let arr = [1, 2, 3];
arr = arr.map(x => x * 2);
console.log(arr); // [2, 4, 6]

用第三个参数

let arr = [1, 2, 3];
arr.map((item, index, array) => {
    array[index] = item * 2;
})
console.log(arr); // [2, 4, 6]

自己手写一个map

根据上边我们分析的map函数的参数回调函数,回调的参数以及返回值,我们不难写出以下代码:

Array.prototype._map = function (callback, ins) {
    let res = [];
    for (let i = 0; i < this.length; i++) {
        res[i] = callback.call(ins || window, this[i], i, this)
    }
    return res;
};

给数组的原型链上拓展一个_map方法,该方法接收两个参数,

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

回调函数的this指针为_map方法的第二个参数或者全局对象window,

我们使用call方法将this指向ins,

然后this[i]数组项作为回调函数的第一个参数,

下标i作为回调函数的第二个参数,

原数组this作为回调函数的第三个参数

测试

[1, 2, 3]._map((item, index, arr) => { console.log(item, index, arr)});

14cf68f261231e36db552e8b62e960a.png

完全没毛病!

完善

上述实现是最最简版的实现,没有限制参数的类型,必填等,我想留给小伙伴们自己去探索也许会更好。

疑问

为啥上述的this是原数组?

215809955b00978fd67ce6e77b338a1.png

啥也不说了,有图有真相!

结语

今天关于数组map的介绍就讲到这里,关注我获取更多有关数组方法的讲解,后续会持续更新。我是末世未然,一个爱折腾的新晋奶爸,祝好