Кто они такие?

Методы массива, которые используют их короткую длину и лаконичный синтаксис.

// short and sweet
let sum = arr.reduce((acc, value) => acc + value, 0);
// too many lines for a simple sum
let sum = 0;

for(let i = 0; i < arr.length; i++) {
	sum += arr[i];
}

Что они делают?

Все эти методы массива перебирают каждый элемент массива и делают что-то для каждого из них. Это что-то указано как функция обратного вызова.

Обратите внимание, что метод дает вашему обратному вызову доступ к трем ценным частям данных. Элемент, индекс и ссылка на массив.

  • Единственная разница в том, что каждый делает что-то другое после выполнения функции обратного вызова для каждого элемента.
  • forEach → ничего
  • filter → создать новый массив и нажать элементы, у которых есть связанный обратный вызов, возвращающий true
  • map → создать новый массив и нажать все элементы после их изменения с обратным вызовом
  • reduce → инициализировать накопленный результат и создавать его с каждой итерацией

Мои реализации

Array.prototype.forEach

Array.prototype.myForEach = function(callback) {
    let array = this;
    let length = this.length;

    for(let i = 0; i < length; i++) {
            let element = this[i];
            let index = i;
            callback(element, index, array);
        }
    };
    const arr = [1, 2, 3];

arr.myForEach((element, index, array) => console.log(`${index} : ${element} : ${array}`));

Array.prototype.map

Array.prototype.myMap = function(callback) {
    const mappedArray = [];

    let array = this;
    let length = this.length;

    for(let i = 0; i < length; i++) {
        let element = this[i];
        let index = i;

        mappedArray.push(callback(element, index, array));
    }

    return mappedArray;
}

const arr = [1, 2, 3];

console.log(arr.myMap((element, index) => element + index));

Array.prototype.filter

Array.prototype.myFilter = function(callback) {
    const filtered = [];

    const array = this;
    const length = this.length;

    for(let i = 0; i < length; i++) {
        let index = i;
        let element = this[i];
        
        if(callback(element, index, array)) {
            filtered.push(element);
        }
    }

    return filtered;
}

const arr = [1, 2, 3];

console.log(arr.myFilter((element) => element > 1));

Array.prototype.reduce

Array.prototype.myReduce = function(...args) {
    let array = this;
    let length = array.length;
    let [callback, initialValue] = args;

    let accumulator = null;
    let startIndex = null;

    // Handles initial value being passed in
    if(args.length === 2) {
        accumulator = initialValue;
        startIndex = 0;
    }
    // Handles initial value not being passed in
    else {
        accumulator = array[0];
        startIndex = 1;
    }

    for(let i = startIndex; i < length; i++) {
        let currentIndex = i;
        let currentValue = array[i];

        accumulator = callback(accumulator, currentValue, currentIndex, array);
    }

    return accumulator;
};

const arr = [1, 2, 3];

console.log(arr.myReduce((accu, current) => accu + current, 10));