Reinhard: .map() auf leeres Array

Hey,

ich habe da mal eine Frage zu folgender Situation:

var arr = Array(5).map(function() {
    return Math.floor(Math.random() * (10 - 1 + 1)) + 1;
});

Ich würde gerne - in einem Abwasch - ein Array mit einer bestimmten Länge erzeugen und gleich mit Zufallszahlen bestücken. Eigenartigerweise wird die map-Funktion kein einziges Mal aufgerufen. Mit .reduce() geht es ebensowenig - mit .fill() aber schon:

var arr = Array(5).fill(0).map(function() {
    return Math.floor(Math.random() * (10 - 1 + 1)) + 1;
});

Kann mir jemand erklären, warum das so ist?

Reinhard

  1. Hallo Reinhard

    ich habe da mal eine Frage zu folgender Situation:

    var arr = Array(5).map(function() {
        return Math.floor(Math.random() * (10 - 1 + 1)) + 1;
    });
    

    Ich würde gerne - in einem Abwasch - ein Array mit einer bestimmten Länge erzeugen und gleich mit Zufallszahlen bestücken. Eigenartigerweise wird die map-Funktion kein einziges Mal aufgerufen. Mit .reduce() geht es ebensowenig - mit .fill() aber schon:

    var arr = Array(5).fill(0).map(function() {
        return Math.floor(Math.random() * (10 - 1 + 1)) + 1;
    });
    

    Kann mir jemand erklären, warum das so ist?

    Es werden beim Setzen der Eigenschaft length eines Arrays, egal ob dies durch den Konstruktor oder von Hand geschieht, grundsätzlich keine Eigenschaften auf dem Arrayobjekt definiert. Es werden lediglich Elemente des Arrays gelöscht, wenn der an length zugewiesene Wert kleiner ist als der vorherige Wert.

    const array = Array(5);
    
    console.log(array.hasOwnProperty(2)); // false
    

    Beim Aufruf der Methode map werden zwar alle Indizes bis zur Länge des Arrays durchlaufen, aber bevor die Rückruffunktion aufgerufen wird, findet erst eine Prüfung statt, ob für den jeweiligen Index auch tatsächlich eine Eigenschaft definiert ist, so wie bei der Prüfung mit hasOwnProperty in dem Beispiel oben. Da durch das Setzen der Eigenschaft length allein jedoch keine Objekteigenschaften definiert werden, fällt dieser Test in deinem Code entsprechend immer negativ aus, mit der Folge, dass deine Rückruffunktion nicht aufgerufen wird.

    Bei der Methode fill findet eine solche Prüfung jedoch nicht statt. Das heißt, auch hier werden, sofern nichts anderes bestimmt wurde, alle Indizes bis zum Wert der Eigenschaft length durchlaufen, aber die Wertzuweisung wird nicht davon abhängig gemacht, ob eine Eigenschaft mit dem entsprechenden Index auch wirklich existiert. Ist dies nicht der Fall, dann wird sie einfach automatisch definiert und dann der jeweilige Wert zugewiesen. Deswegen funktioniert dein zweites Codebeispiel.

    Gruß,

    Orlok

    1. Hey,

      Beim Aufruf der Methode map werden zwar alle Indizes bis zur Länge des Arrays durchlaufen, aber bevor die Rückruffunktion aufgerufen wird, findet erst eine Prüfung statt, ob für den jeweiligen Index auch tatsächlich eine Eigenschaft definiert ist, so wie bei der Prüfung mit hasOwnProperty in dem Beispiel oben. Da durch das Setzen der Eigenschaft length allein jedoch keine Objekteigenschaften definiert werden, fällt dieser Test in deinem Code entsprechend immer negativ aus, mit der Folge, dass deine Rückruffunktion nicht aufgerufen wird.

      Aah, das macht Sinn. Schon wieder was dazu gelernt. Danke!

      Reinhard