如何手动实现map(forEach以及filter也类似)

思路

map 迭代方法接收两个参数:

  • 对每一项执行的函数
    • 该函数接收三个参数:
      • 数组项的值
      • 数组项的下标
      • 数组对象本身
  • 指定 this 的作用域对象

map 方法返回每次函数调用结果组成的数组。

代码表示:

arr.map(function(item, index, arr) {}, this);

实现

由此,实现 fakeMap 方法如下

方法一:

Array.prototype.fakeMap = function fakeMap(fn, context) {
  if (typeof fn !== "function") {//判断fn是否能为函数,如果不是,跑出错误
    throw new TypeError(`${fn} is not a function`);
  }
  
  let arr = this;
  let temp = [];
  for (let i = 0; i < arr.length; i++) {
    // 迭代执行
    let result = fn.call(context, arr[i], i, arr);
    temp.push(result);
  }
  return temp;
};

检测:

let arr = ["x", "y", "z"];

arr.fakeMap((item, index, arr) => console.log(item, index, arr));

输出:

x 0 [ ‘x’, ‘y’, ‘z’ ]
y 1 [ ‘x’, ‘y’, ‘z’ ]
z 2 [ ‘x’, ‘y’, ‘z’ ]

this 指向:

let arr = ["x", "y", "z"];
let obj = { a: 1 };

arr.fakeMap(function() {
  console.log(this.a);
}, obj);

输出

1
1
1

更新

Array.prototype.myMap = function (fn, context) {
  const array = this
  context = Object(context) || global   // 严格模式下
  const resultArr = []
  
  for (let i = 0; i < array.length; i++) {
    let item = array[i]
    result = fn.call(context, item, i, array)
    resultArr.push(result)
  }
  return resultArr
};

注: 严格模式下,context 为 null 或 undefined 时 Object(context) 返回空对象,不会被赋值为global

方法二:  

Array.prototype.myMap = function () {
  var arr = this
  var [fn, thisValue] = Array.prototype.slice.call(arguments)
  var result = []
  for (var i = 0; i < arr.length; i++) {
    result.push(fn.call(thisValue, arr[i], i, arr))
  }
  return result
}
var arr0 = [1, 2, 3]
console.log(arr0.myMap(v => v + 1))
原文地址:https://www.cnblogs.com/art-poet/p/12522474.html