JavaScript/Objekte/Array/from

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Die Methode from des Konstruktors Array kann dazu verwendet werden, mit den Elementen eines Array-ähnlichen oder iterierbaren Objektes ein natives Array zu erzeugen. Optional kann eine Rückruffunktion als Argument übergeben werden, die für jedes Element des übergebenen Objektes einmal aufgerufen wird. In diesem Fall wird das von der Methode from erzeugte Array mit den Rückgabewerten dieser Funktion befüllt. Zudem ist die Methode from generisch, das heißt, sie muss nicht zwingend im Kontext des Konstruktors Array aufgerufen werden.


Syntax

Array.from(items[, callback[, thisArg]])


Attribute
Writable true
Enumerable false
Configurable true


Prototyp


Eigenschaften


Beschreibung

Wird die Methode from auf dem Konstruktor Array mit einem Array-ähnlichen oder iterierbaren Objekt als Argument aufgerufen, dann wird eine neue Arrayinstanz erzeugt und zurückgegeben, in welche die Elemente des an die Methode übergebenen Objektes in der selben Reihenfolge eingefügt werden, wie sie in diesem Objekt vorliegen.


Beispiel
function argumentsToArray ( ) {
  return Array.from(arguments);
}

const value = argumentsToArray(16, 32, 64);

console.log(Array.isArray(value)); // true


In diesem Beispiel wird zunächst eine Funktion deklariert, welche die Anweisung enthält, das Resultat des Aufrufs der Methode from zurückzugeben. Die Methode wird dabei mit dem Objekt als Argument aufgerufen, welches über die Funktionsvariable arguments referenziert wird und das die beim Aufruf an die Funktion übergebenen Argumente enthält. Bei dem Objekt arguments handelt es sich nicht um ein Array, aber sowohl um ein Array-ähnliches, als auch um ein iterierbares Objekt. Entsprechend wird von der Methode from ein Array mit den Werten erzeugt, welche der Funktion beim Aufruf übergeben wurden. Die abschließende Prüfung mit der Methode isArray, ob es sich bei dem zurückgegebenen Objekt wirklich um ein Array handelt, fällt entsprechend positiv aus, sodass im Ergebnis der boolesche Wert true in die Konsole geschrieben wird.


Beispiel
function divideByTwo ( ) {
  return Array.from(arguments, value => value / 2);
}

const results = divideByTwo(32, 64, 128);

results.forEach(value => console.log(value)); // 16, 32, 64


Optional kann der Methode from bei ihrem Aufruf als zweites Argument eine Rückruffunktion (Callback) übergeben werden. Diese Funktion wird dann für jedes Element des als erstes Argument übergebenen Objektes einmal aufgerufen und das von der Methode erzeugte Array wird mit den Rückgabewerten der Funktion befüllt. Dieses Aufrufmuster entspricht weitestgehend dem Aufruf der Methode from mit nur einem Argument und dem anschließenden Aufruf der Arraymethode map auf dem zurückgegebenen Array, mit dem Unterschied, dass beim Aufruf der Methode from kein temporäres Array erzeugt wird. Im Gegensatz zur Arraymethode map wird die Rückruffunktion von der Methode from darüber hinaus auch nicht mit drei, sondern nur mit zwei Argumenten aufgerufen, nämlich dem jeweiligen Wert und dem dazugehörigen Index.

Iterierbare Objekte

Als erstes Argument erwartet die Methode from ein Array-ähnliches und oder iterierbares Objekt, das heißt, jedes Objekt welches entweder selbst eine Schnittstelle für die Iteration implementiert hat (Iterable Interface), oder welches über einen Prototypen mit einer solchen Schnittstelle verfügt, kann der Methode from als Argument übergeben werden. Dies gilt für eingebaute iterierbare Objekte wie Arrays, Maps oder auch Sets ebenso wie für selbstdefinierte Objekte, welche über eine entsprechende Schnittstelle verfügen.


Beispiel
const films = new Map([
  ['Martin Scorsese', 'Taxi Driver'],
  ['Stanley Kubrick', 'A Clockwork Orange'],
  ['Orson Welles', 'Citizen Kane']
]);

const array = Array.from(films);

console.log(array.length); // 3


In diesem Beispiel wird zunächst durch den Aufruf des Konstruktors Map eine neue Mapinstanz erzeugt, wobei dem Konstruktor ein Array mit den Einträgen übergeben wird, mit denen die Map initialisiert werden soll. Weil es sich bei Maps um iterierbare Objekte handelt, kann die auf diese Weise erzeugte Map der Methode from als Argument übergeben werden. Da bei der Iteration von Maps standardmäßig für jeden Eintrag ein Array mit dem Schlüssel und dem Wert ausgegeben wird, entspricht das von der Methode from erzeugte Array dem Array, welches dem Konstruktor Map bei dessen Aufruf übergeben wurde.

Array-ähnliche Objekte

Das Objekt, welches der Methode from als erstes Argument übergeben wird, muss allerdings nicht zwingend iterierbar sein. Die Implementation eines Iterable Interface ist also keine Voraussetzung für das Kopieren der Elemente in ein Array. Es genügt, wenn das Objekt über eine Eigenschaft mit dem Namen length verfügt und die Elemente über einen numerischen Index adressiert werden können.


Beispiel
const films = Array.from({
  0 : 'Blade Runner',
  1 : 'Starship Troopers',
  length : 2
});

console.log(Array.isArray(films)); // true

console.log(films[0]); // Blade Runner


In dem Beispiel oben wird der Methode from ein planes Objekt als Argument übergeben, das standardmäßig nicht iterierbar ist. Die in dem Objekt hinterlegten Werte können allerdings über einen ganzzahligen Index angesprochen werden und es wurde eine Eigenschaft mit dem Namen length definiert. Das reicht der Methode from, um ein Array zu erzeugen, dessen Elemente die Werte der auf dem Objekt angelegten Eigenschaften sind.


Beispiel
const NodeList = document.querySelectorAll('section');

const sections = Array.from(NodeList);

console.log(Array.isArray(sections)); // true


Entsprechend kann die Methode from auch verwendet werden, um die in einer NodeList oder einer HTMLCollection enthaltenen Objekte in ein Array zu kopieren. So wird in dem Beispiel oben mit der Methode querySelectorAll eine NodeList mit den Elementen vom Typ section des Dokumentes erzeugt und diese Liste dann in ein Array kopiert. Nach dieser Konvertierung können nun die verschiedenen von Array.prototype vererbten Methoden auf der Liste ausgeführt werden, die für Objekte vom Typ NodeList nicht zur Verfügung stehen.

Generische Verwendung

Es ist nicht zwingend erforderlich, die Methode from im Kontext des Konstruktors Array auszuführen, dessen eigene Methode sie ist, sondern sie kann auch auf anderen Konstruktoren aufgerufen werden. Wird zum Beispiel eine von Array abgeleitete Klasse erstellt, dann wird auf diesem Funktionobjekt automatisch auch eine Referenz auf die Methode from angelegt. Wird die Methode nun bei ihrem Aufruf über dieses Funktionsobjekt referenziert, dann wird eine Instanz dieser Klasse erzeugt und zurückgegeben.


Beispiel
const map = new Map( ).set('key', 'value');

class CustomArray extends Array {
  constructor ( ) {
    super(...arguments);
    Object.defineProperty(this, 'type', {
      value : 'CustomArray'
    });
  }
}

const array = CustomArray.from(map);

console.log(array.type); // CustomArray


In diesem Beispiel wird zunächst eine Map erstellt und gespeichert, welcher unter Verwendung der Methode set ein einzelner Eintrag hinzugefügt wird. Danach wird eine von Array abgeleitete Klasse deklariert, in deren Pseudomethode constructor eine Eigenschaft für die zu erzeugenden Instanzen definiert wird. Schließlich wird from auf der abgeleiteten Klasse aufgerufen und dabei die Map als Argument übergeben. Der Rückgabewert der Methode ist nun eine Instanz der abgeleiteten Klasse, wie die Abfrage der zuvor definierten Eigenschaft zeigt.

Alternativen

Wenn es darum geht, die Elemente eines Array-ähnlichen, beziehungsweise iterierbaren Objektes in ein natives Array zu kopieren, dann kann dies natürlich auch auf andere Weise geschehen, als durch den Aufruf der Methode from. Tatsächlich wurde from erst in der sechsten Edition der Sprache standardisiert und die beschriebene Aufgabe musste bis dato ohnehin anders gelöst werden.


Beispiel
function argumentsToArray ( ) {
  return Array.prototype.slice.call(arguments);
}

var value = argumentsToArray(2, 4, 8);

console.log(Array.isArray(value)); // true


Die klassische Vorgehensweise, zum Beispiel bei der Überführung der Elemente des Objektes arguments in ein echtes Array war, die Arraymethode slice ohne Argumente im Kontext von arguments aufzurufen, wozu man sich üblicherweise der Funktionsmethode call bedient hat. Statt die Methode slice wie in dem Beispiel oben direkt auf Array.prototype anzusprechen, wurde auch oft ein temporäres leeres Array erzeugt, und slice über die Prototypenkette referenziert, da eine solche Notierung etwas kürzer ist. Eine solche Vorgehensweise ist allerdings seit der Einführung der Methode from nicht mehr zu empfehlen, da sie im Vergleich weniger elegant und schlechter lesbar ist.


Beispiel
function argumentsToArray ( ) {
  return [...arguments];
}

const value = argumentsToArray(16, 32, 64);

console.log(Array.isArray(value)); // true


Eine Alternative bei iterierbaren Objekten, also solchen Objekten, welche ein Iterable Interface implementiert haben, ist der sogenannte Spread Operator, der aus drei Punkten besteht. Wird dieser Operator in einem Arrayliteral notiert und ihm ein iterierbares Objekt übergeben, dann fügt er die Elemente dieses Objektes in das Array ein. In dem Beispiel oben wird also ebenfalls ein Array mit den an die Funktion übergebenen Argumenten erzeugt und zurückgegeben. Der Spread Operator wurde allerdings ebenso wie die Methode from erst in der sechsten Edition der Sprache standardisiert und wird unter Umständen noch nicht von allen relevanten Ausführungsumgebungen unterstützt. Die Kompatibilität vorausgesetzt, kann er aber als gleichwertige Alternative zu der Methode from angesehen werden.

Eigene Eigenschaften

Die Methode from besitzt zwei eigene Eigenschaften mit den Namen length und name. Der Wert der Eigenschaft length ist der numerische Wert 1, welcher die Anzahl der formalen Parameter der Methode repräsentiert. Zwar können der Methode from insgesamt bis zu drei Argumente übergeben werden, aber optionale Parameter werden bei der Berechnung der Eigenschaft length von Funktionsobjekten nicht berücksichtigt.


Beispiel
console.info(Array.from.length); // 1

console.info(Array.from.name); // from


Der Wert der Eigenschaft name ist die Zeichenkette from, also der Name der Methode. Beide Eigenschaften sind schreibgeschützt, das heißt sie können nicht durch einfache Zuweisung (Assignment) überschrieben werden, aber da sie konfigurierbar sind, können die Werte durch explizite Definition verändert werden. Darüber hinaus sind beide Eigenschaften standardmäßig nicht abzählbar.

Kompatibilität

Da die Methode from erst in der sechsten Edition der Sprache standardisiert wurde, kann es unter Umständen ratsam sein, vor dem Gebrauch zunächst den allgemeinen Stand der Unterstützung zu überprüfen, was zum Beispiel anhand der Tabelle zur Kompatibilität von kangax geschehen kann. Sofern die Unterstützung noch nicht ausreichend gegeben ist, kann ein Polyfill für die Methode bereitgestellt werden.

Weblinks

  • ECMAScript 2017 (7th Edition, ECMA-262 Draft): Array.from
  • ECMAScript 2015 (6th Edition, ECMA-262): Array.from