使用原生js实现map方法详解

在做题目的时候遇到了这个问题,不是很理解其中的道理,于是就搜索了一番,然后用自己理解的大白话整理了出来。如果有不对的地方,请指出,?️?️

先看代码:

/* 创建一个普通的数组 */
var s = [23, 65, 98, 5];

/* 在数组原型上添加一个方法,这里我命名为 myMap */
Array.prototype.myMap = function (fun, item) { 
            let newArray = []; 
            let arr = this; 
            for (let i = 0; i < arr.length; i++) { 
                /* 调用回调函数处理数据 */
                let result = fun.call(item, arr[i], i, arr); 
                newArray.push(result);
            }
            return newArray; 
        };

/* 调用封装的 myMap 方法 */
var new_s = s.myMap(function (value) {  
            return value * 2;
        });
        console.log(new_s); // 打印结果: [46, 130, 196, 10]

分解:

  • fun: 接收的是 s 数组的处理函数,
  • item: 接收的是 s 数组(要被this指向的数组,哪个数组调用的myMap方法,item 接收的就是哪个数组)
Array.prototype.myMap = function (fun, item) {
  •  这个空数组用来接收遍历完成后的新数组
let newArray = [];
  • 这个 this 指向的是函数的调用者,也就是调用这个 myMap 方法的数组(s数组)就是 this
let arr = this; 
  •  arr.length: 这个 arr 指的就是调用 myMap 方法的那个数组(因为把this赋值给了它,在这里就是 s 数组里的元素长度)
for (let i = 0; i < arr.length; i++) {
  • call: 可以改变 this 的指向(第一个参数就是让this指向的对象,后面的参数就是调用函数时传递的实参);可以调用函数(平时调用函数都是,fun(),但是就只能单纯调用)
  • arr[i]: 被遍历的数组里面的第 i 个,就是当前遍历到的数组元素
  • i: 当前元素索引
  • arr: 被遍历的数组
let result = fun.call(item, arr[i], i, arr);
  • 经过我在控制台调试发现,每个元素经过 for 循环后就会传递给 s 数组里的 value(形参) 进行接收,然后做相应的处理,最后才把处理完之后的元素推进 newArray 数组 
newArray.push(result);}
  • 返回处理后的新数组 
return newArray;}
  •  s: 就是原始数组
  • myMap:就是利用原生js封装的添加到数组原型上的一个方法
  • value: 接收的就是 s 数组里当前遍历的元素(也就是接收的“fun.call(item, arr[i], i, arr)” 里的 arr[i])
var new_s = s.myMap(function (value) {
  • 返回当前数组元素的处理结果
return value * 2;});
  • new_s接收到的是,返回的新数组 newArray 
console.log(new_s);

 证明myMap函数的 “fun” 形参接收的是s数组的处理函数:

起初我不明白 fun 参数接收的是什么,然后我就把调用 myMap 的函数给拆开写,解决了我的疑惑与不确定。

代码:

Array.prototype.myMap = function (fun, item) { 
            let newArray = []; 
            let arr = this; 
            for (let i = 0; i < arr.length; i++) { 
                let result = fun.call(item, arr[i], i, arr);
                newArray.push(result); 
            }
            return newArray; 
        };

// 我拆开写的函数
let callback = function (value) {
            return value * 2;
        }
        var new_s = s.myMap(callback);
        // var new_s = s.myMap(); 

 解读:

“ var new_s = s.myMap(callback)” 的 callback(接收匿名函数的变量) 在这里就是实参,如果我不把它传入,就会报一个错: “ Cannot read properties of undefined (reading 'call')无法读取未定义的属性(读取“call”) ”,意思就是,没有读取到有属性调用了 call,而在 myMap 方法中调用 call 的,是 “fun” 参数,足以证明,“fun”参数接收到的就是 “s.myMap(callback)” 中作为参数传入的 callback 函数❗️所以 “fun” 接收的就是 s 数组调用 myMap 方法时指定的处理函数。

总结:

以上仅代表个人观点,如果你也遇到这样的疑惑并对你有所帮助,帮忙点个赞喔。对我写的内容有不理解的可以向我询问,乐意解答,质疑的内容也请指出,欢迎和我一起探讨!?

 


版权声明:本文为apple_59018571原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。