Vyhledávání na webu

javascript - forEach na 'novém poli' nedělá to, co očekávám


Právě se učím používat JS vyšší řádové funkce (map, forEach, reduce, atd.) a narazil jsem na zmatení. Snažím se napsat jednoduchou funkci 'range', ale nemůžu naplnit své výstupní pole. Toto je cíl:

range(1, 4) // [1, 2, 3, 4]

Dostávám toto:

[undefined × 4]

Tady je můj kód:

 function range(num1, num2) {
      var rangeArr = new Array((num2 + 1) - num1);
      return rangeArr.map(function(e, i, arr) {return arr[i] = num1 + i});
    }

Co mi tu chybí? Pokud mohu soudit, problém se zdá mít něco společného s tím, jak používám ‚new Array‘, ale dál jsem ztracený.

Oh, a tady je ta část, která mě opravdu mate. Toto funguje dobře:

function bleck() {
    var blah = [1, 2, 3, 4];
    var x = 'wtf';
    return blah.map(function(e, i, arr) {return arr[i] = x})
}

["wtf", "wtf", "wtf", "wtf"]

Díky!!

Odpověď č. 1

Metoda forEach iteruje přes indexy pole. Zajímavé je, že když vytvoříte nové pole pomocí new Array(n), neobsahuje žádné indexy. Místo toho jen nastaví svou vlastnost .length.

> var a = new Array(3);
> console.info(a)
[]
> console.info([undefined, undefined, undefined])
[undefined, undefined, undefined]

MDN popisuje forEach a konkrétně uvádí:

forEach provede poskytnutou zpětnou volání (callback) jednou pro každý prvek pole, který má přiřazenou hodnotu. Nevykonává se pro indexy, které byly smazány nebo vynechány.

Tady je pěkná technika, jak získat pole s prázdnými, ale existujícími indexy.

var a = Array.apply(null, Array(3));

Toto funguje, protože .apply „rozšiřuje“ vynechané prvky do správných argumentů a výsledkem je něco jako Array(undefined, undefined, undefined).

Odpověď č. 2

Pole je definováno se 4 položkami, z nichž každá je nedefinovaná.

Map nebude procházet nedefinované položky, přeskočí je.

zpětná funkce je volána pouze pro indexy pole, kterým byly přiřazeny hodnoty; není volána pro indexy, které jsou nedefinované, které byly odstraněny nebo kterým nikdy nebyly přiřazeny hodnoty.

https://developer.mozilla.org/cs/docs/Web/JavaScript/Reference/Global_Objects/Array/map