Ulepszamy nasz forEach o rzeczy, jakich oryginalny nie ma: możliwość używania break i continue. Sztuka dla sztuki.

Najpierw przypomnienie poprzedniej pracy:

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

Ok, dajemy skipWhen:

Array.prototype.myForEach = function(callback, thisArg, skipWhen=()=>false){
    var array = this;
    thisArg = thisArg || this;
    for (var i = 0; i < this.length; i++) {
       if(skipWhen.call(thisArg, array[i], i, array)){
            continue;
       }
       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'}, (el) => el % 2 === 0);

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

Zakładam, że warunek chcemy sprawdzić przed wywołaniem callbacka głównego. Tak jest najlogiczniej. Teraz breakWhen:

Array.prototype.myForEach = function(callback, thisArg, 
    skipWhen=()=>false,
    breakWhen=()=>false){

    var array = this;
    thisArg = thisArg || this;

    for (var i = 0; i < this.length; i++) {

       if(breakWhen.call(thisArg, array[i], i, array) === true){
          break;
       }

       if(skipWhen.call(thisArg, array[i], i, array) === true){
          continue;
       }
       

       callback.call(thisArg, array[i], i, array);
    }   
 }

Założyłem, że mogą być kolizje, czyli warunek dla breakWhen i dla skipWhen może być prawdziwy w obu przypadkach. Wtedy – break ma pierwszeństwo.

Jeżeli warunek breakowy daje fałsz, sprawdzamy warunek skipowy. Jeżeli też fałsz, wykonujemy callback.

 let arr = [1,2,10,3];


 arr.myForEach(function(el, idx, arr){
    if(idx === 1){
        console.log("Arr: ", arr.toString());
        console.log(this.name);
    }
    console.log(el);
    }, 
 {name: 'John'}, 
 (el) => el % 2 !== 0, 

);
//Arr
//John
//2 
//10

Teraz dwie funkcje:

 arr.myForEach(function(el, idx, arr){
    if(idx === 1){
        console.log("Arr: ", arr.toString());
        console.log(this.name);
    }
    console.log(el);
    }, 
 {name: 'John'}, 
 (el) => el % 2 !== 0, 
 (el, idx) => el + idx === 13

);

//Arr 1,2,11,3
//John
//2 

1 zostało pominięte, bo nieparzyste. 11 wywołało break, bo 11 + 2 (indeks) to 13. Tak to mniej więcej działa. Powinniśmy już być mistrzami przekazywania callbacków!