Mozilla's getting a new look. What do you think? https://mzl.la/brandsurvey

Array.prototype.map()

DIe Map() Methode wendet auf jedes Element des Arrays die bereitgestellte Funktion an und erstellt ein neues Array als Ergebnis.

Syntax

arr.map(callback[, thisArg])

Parameter

callback
Funktion die ein Element für das neue Array erstellt, es werden drei Argumente akzeptiert: 
currentValue
Das aktuell verarbeitete Element.
index
Der Index des aktuell verarbeiteten Elementes.
array
Das Array, auf das  map angewendet wurde.
thisArg
Optional. Wert der als this verwendet wird, wenn callback ausgeführt wird.

Rückgabewert

Ein neues Array.

Beschreibung

Map wendet die bereitgestellte callback Funktion, der Reihe nach, auf jedes einzelne Element in dem Array an und erstellt ein neues Array von den Ergebnissen. callback wird nur auf Indizes angewandt, die einen Wert besitzen, auch der Wert undefined. Sie wird nicht für fehlende Elemente im Array aufgerufen (das sind Indizes, die nie gesetzt wurden, die gelöscht wurden oder denen nie ein Wert zugewiesen wurde).

callback wird mit drei Argumenten aufgerufen: dem Wert des Elementes, dem Index des Elements und dem Array-Objekt. 

Falls thisArg angegeben ist, wird es zur callback Funktion weitergereicht und als this benutzt. Ansonsten hat thisArg den Wert undefined. Der this-Wert, der letztlich vom callback verwendet wird, wird anhand der Regeln, nach denen this für eine Funktion ermittelt wird ermittelt.

map ändert das Array, auf dem es aufgerufen wird, nicht. (Aber callback kann natürlich das Array ändern.)

Die Anzahl der Elemente, die von map angenommen werden, wird vor dem ersten Ausführen der callback Funktion festgelegt. Wird ein Element im Nachhinein durch callback hinzugefügt, wird es von map nicht berücksichtigt. Falls ein Wert im Array verändert wird, erhält callback den Wert, den das Element in dem Moment hat, wenn der callback diesen benötigt. Wird ein Wert gelöscht wird es von map nicht beachtet. 

Beispiele

Erstellen eines Arrays mit Quadratzahlen aus einem Array mit Zahlen

Der folgende Code nimmt ein Array mit Nummern und erstellt ein neues Array mit den Quadratzahlen des ersten Arrays.

var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots ist [1, 2, 3], numbers ist immernoch [1, 4, 9]

Einsatz von map um Objekt in ein Array neu zu formieren

Der folgende Quelltext hat ein Array mit Objekten und erstellt ein neues Array mit neu umformatierten Objekten.

var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.map(function(obj){ 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray is now [{1:10}, {2:20}, {3:30}], 
// kvArray is still [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]

 

Abbilden eines Arrays mit Nummern mit einer Funktion mit einem Argument.

Der folgende Code zeigt, wie map arbeitet, wenn die Funktion nur eine Argument besitzt. Während map durch die Array loopt nimmt das Argument den Wert des aktuellen Elementes an. 

var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
  return num * 2;
});
// doubles ist [2, 8, 18]. numbers ist [1, 4, 9]

Generischer Einsatz von map

Dieses Beispiel zeigt, wie map auf einem String arbeiten kann, um ein Array von Bytes im ASCII-Encoding zu bekommen:

var map = Array.prototype.map;
var a = map.call('Hello World', function(x) { return x.charCodeAt(0); });
// a now equals [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

Generischer Einsatz von map und querySelectorAll

Dieses Beispiel zeigt wie man über eine Array mit Elementen, die mit querySelectorAll erstellt wurde, iteriert. In diesem Fall enthält die Array alle <option> HTML-Elemente die ausgewählt wurden.

var elems = document.querySelectorAll('select option:checked');
var values = [].map.call(elems, function(obj) {
  return obj.value;
});

Einsatz von map, um einen String umzukehren

var str = '12345';
[].map.call(str, function(x) {
  return x;
}).reverse().join(''); 

// Output: '54321'
// Bonus: Benutze '===' um zu sehen ob der String ein Palindrom ist

Besondere Anwendungsfälle

(Inspiriert von diesem Blogpost)

Häufig wird die callback Funktion mit nur einem Argument gebraucht. Andere Funktionen werden auch häufig mit nur einem Argument benutzt obwohl Sie optional Argumente akzeptieren.  Diese Vorgehensweise verwirrend sein.

// Consider:
['1', '2', '3'].map(parseInt);
// Man erwartet [1, 2, 3]
// Das Ergebnis ist [1, NaN, NaN]

// parseInt wird oft mit nur einem Argument genutzt, aber akzeptiert zwei.
// Das erste Argument ist ein Ausdruck und die zweite der Radix.
// Array.prototype.map reicht 3 Argumente an die callback funktion:
// Das Element, den Index, die Array 
// parseInt ignoriert das dritte Argument, aber nicht das zweite,
// das kann zu einem unerwarteten Ergebniss führen.
// Der Blogpost geht in genaueren Detail darauf ein.

function returnInt(element) {
  return parseInt(element, 10);
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]
// Actual result is an array of numbers (as expected)

// A simpler way to achieve the above, while avoiding the "gotcha":
['1', '2', '3'].map(Number); // [1, 2, 3]

Polyfill

map wurde dem ECMA-262 Standard in der fünften Edition hinzugefügt; deswegen kann es sein, dass es nicht in allen Implementierungen des Standards vorhanden ist. Falls map nicht nativ unterstützt wird, kann der folgende Code am Anfang der Skripte eingefügt werden. Der folgende Algorithmus ist identisch mit dem in der fünften Edition des ECMA-265 Standards festgelegten. Es wird angenommen, dass  Object, TypeError und Array unverändert sind und dass callback.call zum Standardwert von Function.prototype.call evaluiert.

// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.io/#x15.4.4.19
if (!Array.prototype.map) {

  Array.prototype.map = function(callback, thisArg) {

    var T, A, k;

    if (this == null) {
      throw new TypeError(' this is null or not defined');
    }

    // 1. Let O be the result of calling ToObject passing the |this| 
    //    value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get internal 
    //    method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
    if (arguments.length > 1) {
      T = thisArg;
    }

    // 6. Let A be a new array created as if by the expression new Array(len) 
    //    where Array is the standard built-in constructor with that name and 
    //    len is the value of len.
    A = new Array(len);

    // 7. Let k be 0
    k = 0;

    // 8. Repeat, while k < len
    while (k < len) {

      var kValue, mappedValue;

      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty internal 
      //    method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      if (k in O) {

        // i. Let kValue be the result of calling the Get internal 
        //    method of O with argument Pk.
        kValue = O[k];

        // ii. Let mappedValue be the result of calling the Call internal 
        //     method of callback with T as the this value and argument 
        //     list containing kValue, k, and O.
        mappedValue = callback.call(T, kValue, k, O);

        // iii. Call the DefineOwnProperty internal method of A with arguments
        // Pk, Property Descriptor
        // { Value: mappedValue,
        //   Writable: true,
        //   Enumerable: true,
        //   Configurable: true },
        // and false.

        // In browsers that support Object.defineProperty, use the following:
        // Object.defineProperty(A, k, {
        //   value: mappedValue,
        //   writable: true,
        //   enumerable: true,
        //   configurable: true
        // });

        // For best browser support, use the following:
        A[k] = mappedValue;
      }
      // d. Increase k by 1.
      k++;
    }

    // 9. return A
    return A;
  };
}

Spezifikationen

Spezifikation Status Kommentar
ECMAScript 5.1 (ECMA-262)
Die Definition von 'Array.prototype.map' in dieser Spezifikation.
Standard Initiale Definition. Implementiert in JavaScript 1.6.
ECMAScript 2015 (6th Edition, ECMA-262)
Die Definition von 'Array.prototype.map' in dieser Spezifikation.
Standard  
ECMAScript 2017 Draft (ECMA-262)
Die Definition von 'Array.prototype.map' in dieser Spezifikation.
Entwurf  

Browserkompatibilität

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Ja) 1.5 (1.8) 9 (Ja) (Ja)
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Ja) (Ja) 1.0 (1.8) (Ja) (Ja) (Ja)

Siehe auch

Schlagwörter des Dokuments und Mitwirkende

 Mitwirkende an dieser Seite: schlagi123, justb81, mexn, leMaik, derhagen, Arminmsg
 Zuletzt aktualisiert von: schlagi123,