Array.prototype.forEach()

104 阅读1分钟

函数特点

  • 返回undefined
  • 循环索引只能从0开始,无法干预
  • 若forEach的回调函数是箭头函数,this参数会被忽略
  • 在forEach的回调函数中使用continue会报错,若要实现continue的功能,可以用return来替代
const ary = [1,2,3,4,5,6];
ary.forEach((item, index) => {
    if (index < 3) return;
    console.log(index); // 依次打印出3, 4, 5
});
  • 已删除或者空槽的项(稀疏数组)会跳过回调函数
const ary = [1,,3,4];
ary.length = 4;
let sum = 0;
ary.forEach((item) => {
    console.log(item); // 分别打印出1,3,4
    sum++;
});
console.log(sum); // 3
  • 除了抛出异常,无法中止或跳出循环【暴力实现break效果】
const ary = [1,2,3,4];
try {
    ary.forEach((item, index) => {
        if (index === 2) throw index;
    });
} catch(err) {
    console.log(`当下标来到${err}时停止循环`); // 当下标来到2时停止循环
}

函数用法

// 回调函数 - 数组每个元素都会执行的函数
// element - 当前元素
// index - 当前元素的索引
// array - 调用forEach()方法的数组
// this - 当前执行回调函数时的this值
Array.prototype.forEach(function(element , index, array) => {}, this);

const ary = [1,2,3,4,5,6,7];
ary.forEach((element, index, array) => {
    console.log(element, index, array, this);
}, this);

使用场景

  • 遍历数组内容
  • 扁平化数组【当然也可以使用Array.prorotype.flat()】
const flatFn = (ary) => {
    const result = [];
    ary.forEach((item) => {
        if (Array.isArray(item)) {
            result.push(...flatFn(item));
        } else {
            result.push(item);
        }   
    });
    return result;
};
const ary = [[1, [2]], [3,4,[5]], [6, [[7]]]];
console.log(flatFn(ary)); // [1, 2, 3, 4, 5, 6, 7]

手写实现

Array.prototype.myForEach = function(callback, thisArg) {
    if (this === null || this === undefined) {
        throw new TypeError('this is null or undefined');
    }
    if (typeof callback !== 'function') {
        throw new TypeError(callback + 'is not a function');
    }
    const obj = Object(this);
    const len = obj.length >>> 0;
    let i = 0;
    while (i < len) {
        if (i in obj) {
            callback.call(thisArg, obj[i], i, obj);
        }
        i++;
    }
}