返回

用JavaScript写Map、forEach、filter和reduce:编程实践和示例

前端

引 言

数组是JavaScript中常用的数据结构,而Array.prototype上有很多方法,可以很方便的实现各种循环、过滤对数组做很多的处理。这里主要记录自己怎么实现几个方法map、forEach、filter、reduce,怎么使用就不多做讲解了因为在mdn 中 Array或者别人的文章中很多都讲的很好很详细了。

实 现 原 理

map()

// 使用 reduce 替代 map,实现数组元素的映射
Array.prototype.myMap = function(callback, thisArg) {
  if (!Array.isArray(this)) {
    throw new TypeError('`this` must be an array');
  }

  if (callback === null || typeof callback !== 'function') {
    throw new TypeError('`callback` must be a function');
  }

  const result = [];
  for (let i = 0; i < this.length; i++) {
    const currentValue = this[i];
    const mappedValue = callback.call(thisArg, currentValue, i, this);
    result.push(mappedValue);
  }

  return result;
};

forEach()

// 使用 for 循环,实现数组元素的遍历
Array.prototype.myForEach = function(callback, thisArg) {
  if (!Array.isArray(this)) {
    throw new TypeError('`this` must be an array');
  }

  if (callback === null || typeof callback !== 'function') {
    throw new TypeError('`callback` must be a function');
  }

  for (let i = 0; i < this.length; i++) {
    const currentValue = this[i];
    callback.call(thisArg, currentValue, i, this);
  }
};

filter()

// 使用 reduce 替代 filter,实现数组元素的过滤
Array.prototype.myFilter = function(callback, thisArg) {
  if (!Array.isArray(this)) {
    throw new TypeError('`this` must be an array');
  }

  if (callback === null || typeof callback !== 'function') {
    throw new TypeError('`callback` must be a function');
  }

  const result = [];
  for (let i = 0; i < this.length; i++) {
    const currentValue = this[i];
    const keep = callback.call(thisArg, currentValue, i, this);
    if (keep) {
      result.push(currentValue);
    }
  }

  return result;
};

reduce()

// 使用 for 循环,实现数组元素的归并
Array.prototype.myReduce = function(callback, initialValue) {
  if (!Array.isArray(this)) {
    throw new TypeError('`this` must be an array');
  }

  if (callback === null || typeof callback !== 'function') {
    throw new TypeError('`callback` must be a function');
  }

  let accumulator = initialValue;
  let startIndex = 0;

  if (accumulator === undefined) {
    accumulator = this[0];
    startIndex = 1;
  }

  for (let i = startIndex; i < this.length; i++) {
    const currentValue = this[i];
    accumulator = callback(accumulator, currentValue, i, this);
  }

  return accumulator;
};

应 用 实 例

map()

const numbers = [1, 2, 3, 4, 5];

// 使用 map() 将数组中的元素乘以 2
const doubledNumbers = numbers.myMap((num) => num * 2);

console.log(doubledNumbers); // [2, 4, 6, 8, 10]

forEach()

const fruits = ['apple', 'banana', 'cherry', 'durian', 'elderberry'];

// 使用 forEach() 打印数组中的元素
fruits.myForEach((fruit) => console.log(fruit));

// apple
// banana
// cherry
// durian
// elderberry

filter()

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 使用 filter() 过滤出数组中大于 5 的元素
const filteredNumbers = numbers.myFilter((num) => num > 5);

console.log(filteredNumbers); // [6, 7, 8, 9, 10]

reduce()

const numbers = [1, 2, 3, 4, 5];

// 使用 reduce() 计算数组中元素的总和
const sum = numbers.myReduce((accumulator, currentValue) => accumulator + currentValue);

console.log(sum); // 15

总 结

通过本文,我们深入了解了Array.prototype上几个常用方法map、forEach、filter和reduce的实现原理和应用。这些方法可以帮助我们轻松的处理数组中的元素,实现各种循环、过滤对数组做很多的处理。希望本文能够帮助大家更好地理解JavaScript中数组处理的基本操作。

参考 资料