Piszemy polyfill dla funkcji forEach – tak, aby działał identycznie, jak oryginał. Do dzieła.

Iteracja pierwsza – callback z elementem:

Array.prototype.myForEach = function(callback){
    for (var i = 0; i < this.length; i++) {
       callback(this[i]);
    }   
 }

 let arr = [1,2,3];

 arr.myForEach(function(el){
    console.log(el);
 });

 //1
 //2
 //3

Iteracja druga – callback z elementem i indeksem:

Array.prototype.myForEach = function(callback){
    for (var i = 0; i < this.length; i++) {
       callback(this[i],i);
    }   
 }

 let arr = [1,2,3];

 arr.myForEach(function(el){
    console.log(el);
 });

 //1
 //2
 //3

 arr.myForEach(function(el, idx){
    console.log(`Idx: ${idx}, El: ${el}`);
 });
 
//  Idx: 0, El: 1 
//  Idx: 1, El: 2 
//  Idx: 2, El: 3

Iteracja trzecia: callback z elementem, indeksem i tablicą:

Array.prototype.myForEach = function(callback){
    for (var i = 0; i < this.length; i++) {
       callback(this[i],i, this);
    }   
 }

 let arr = [1,2,3];


 arr.myForEach(function(el, idx, arr){
    if(idx === 0){
        console.log("Arr: ", arr.toString());
    }
    console.log(`Idx: ${idx}, El: ${el}`);
 });

// Arr:  1,2,3 
// Idx: 0, El: 1 
// Idx: 1, El: 2 
// Idx: 2, El: 3

Iteracja czwarta: opcjonalne this-binding:

Array.prototype.myForEach = function(callback, thisArg){
    var array = this;
    thisArg = thisArg || this;
    for (var i = 0; i < this.length; i++) {
       callback.call(thisArg, array[i], i, array);
    }   
 }

 let arr = [1,2,3];


 arr.myForEach(function(el, idx, arr){
    if(idx === 0){
        console.log("Arr: ", arr.toString());
        console.log(this.name);
    }
    console.log(`Idx: ${idx}, El: ${el}`);
 }, {name: 'John'});

// Arr:  1,2,3 
// John
// Idx: 0, El: 1 
// Idx: 1, El: 2 
// Idx: 2, El: 3