# 数组遍历那些事儿

# 说明

本文用基本的语法,还原 JavaScript 的 Array 对象在 Prototype 原型链上定义的遍历方法

# forEach

// Array.prototype.forEach() 遍历
// 为数组中的每个元素执行一次回调函数。
Array.prototype.myforEach = function (fn) {
  const array = this;
  for (let i = 0; i < array.length; i++) {
    let item = array[i];
    fn(item, i, array);
  }
};
// 测试用例
[1, 2, 3].myforEach((item) => console.log(item));
// 1
// 2
// 3

# every

// Array.prototype.every() 每一个
// 如果数组中的每个元素都满足测试函数,则返回 true,否则返回 false。
Array.prototype.myevery = function (fn) {
  const array = this;
  let count = 0;
  for (let i = 0; i < array.length; i++) {
    let item = array[i];
    if (fn(item, i, array)) {
      count++;
    }
  }
  return array.length == count;
};
// 测试用例
let flag = [2, 4, 6, 8, 10].myevery((item) => item % 2 == 0);
console.log(flag);
// true

# some

// Array.prototype.some() 有一个
// 如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。
Array.prototype.mysome = function (fn) {
  const array = this;
  for (let i = 0; i < array.length; i++) {
    let item = array[i];
    if (fn(item, i, array)) {
      return true;
    }
  }
  return false;
};
// 测试用例
let flag = [1, 3, 5, 7, 9].mysome((item) => item % 2 == 0);
console.log(flag);
// false

# find

// Array.prototype.find()
// 找到第一个满足测试函数的元素并返回那个元素的值,如果找不到,则返回 undefined。
Array.prototype.myfind = function (fn) {
  const array = this;
  for (let i = 0; i < array.length; i++) {
    let item = array[i];
    if (fn(item, i, array)) {
      return item;
    }
  }
  return undefined;
};
// 测试用例
let target = [1, 3, 5, 7, 9, 10].myfind((item) => item % 2 == 0);
console.log(target);
// 10

# findIndex

// Array.prototype.findIndex()
// 找到第一个满足测试函数的元素并返回那个元素的索引,如果找不到,则返回 -1。
Array.prototype.myfindIndex = function (fn) {
  const array = this;
  for (let i = 0; i < array.length; i++) {
    let item = array[i];
    if (fn(item, i, array)) {
      return i;
    }
  }
  return -1;
};
// 测试用例
let index = [1, 3, 5, 7, 9, 10].myfindIndex((item) => item % 2 == 0);
console.log(index);
// 5

# map

// Array.prototype.map() 映射
// 返回一个由回调函数的返回值组成的新数组。
Array.prototype.myMap = function (fn) {
  const array = this; //指向数组实例
  const resultArr = []; //定义一个新数组
  for (let i = 0; i < array.length; i++) {
    let item = array[i]; //取值,传入
    let result = fn(item, i, array); //调用
    resultArr.push(result);
  }
  return resultArr; //返回这个新数组
};
// 测试用例
function greet(greeting) {
  return (item) => greeting + " " + item;
}
const children = ["大雄", "胖虎"];
console.log(children.myMap(greet("早上好")));
// [ '早上好 大雄', '早上好 胖虎' ]

# filter

// Array.prototype.filter()
// 将所有在过滤函数中返回 true 的数组元素放进一个新数组中并返回。

Array.prototype.myfilter = function (fn) {
  const array = this;
  const resultArr = [];
  for (let i = 0; i < array.length; i++) {
    let item = array[i];
    if (fn(item, i, array)) {
      resultArr.push(item);
    }
  }
  return resultArr;
};
// 测试用例
const words = ["spray", "limit", "elite", "exuberant", "destruction", "present"];
let longWords = words.myfilter((word) => word.length > 6);
console.log(longWords);
// [ 'exuberant', 'destruction', 'present' ]

# flat

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat()); // [0, 1, 2, 3, 4]
const arr2 = [0, 1, 2, [[[3, 4]]]];
console.log(arr2.flat(2)); // [0, 1, 2, [3, 4]]
console.log(arr2.flat(Infinity)); // 使用 Infinity,可展开任意深度的嵌套数组 // [0, 1, 2, 3, 4]

# 参考资料

How to get the difference between two arrays in JavaScript? (opens new window)