Array.from() vs. Spread-Syntax

Lesezeit: 7 Minuten

Benutzer-Avatar
jotavejv

Gibt es einen Unterschied zwischen der Verwendung von Array.from(document.querySelectorAll('div')) oder [...document.querySelectorAll('div')]?

Hier ist ein Beispiel:

let spreadDivArray = [...document.querySelectorAll('div')];
console.log(spreadDivArray);

let divArrayFrom = Array.from(document.querySelectorAll('div'));
console.log(divArrayFrom);

Das console.log() wird das gleiche Ergebnis protokollieren.

Gibt es Leistungsunterschiede?

  • Das Gute am Spread-Operator ist, dass er unterstützt Object. Leistung.. idk

    – Halbfreunde

    11. November 2016 um 12:40 Uhr


  • Führen Sie einen Benchmark durch, um herauszufinden, ob es einen Leistungsunterschied gibt. Die Ergebnisse sind wahrscheinlich sehr unterschiedlich, je nachdem, ob Sie sich in einer nativen ES6-Umgebung befinden oder auf ES5 transpilieren.

    Benutzer663031

    11. November 2016 um 12:46 Uhr


  • Der Hauptunterschied ist das Array.from arbeitet mit Array-ähnlichen Objekten, die das Iterator-Protokoll nicht implementieren (dh Symbol.iterator). Selbst mit ES6 und neuen Browserspezifikationen gibt es immer weniger davon.

    – Null

    11. November 2016 um 12:46 Uhr


  • ... ist kein Betreiber!

    – Felix Klinge

    11. November 2016 um 15:56 Uhr


  • Zusätzlich zur Leistung kann es unterschiedliche Obergrenzen für die Arraygröße geben, die diese verarbeiten können. Zumindest in Chrome scheint der Spread-Operator bei Verwendung mit sehr großen Arrays eine “Maximale Aufrufstapelgröße überschritten” zu werfen, während Array.from() funktioniert gut.

    – Peterflynn

    13. Mai um 7:47 Uhr

Benutzer-Avatar
Michał Perłakowski

Verbreiten Element (es ist kein Operator) funktioniert nur mit Objekten, die sind wiederholbar (dh implementieren die @@iterator Methode). Array.from() funktioniert auch bei Array-ähnlichen Objekten (dh Objekten, die die length Eigenschaft und indizierte Elemente), die nicht iterierbar sind. Siehe dieses Beispiel:

const arrayLikeObject = { 0: 'a', 1: 'b', length: 2 };

// This logs ['a', 'b']
console.log(Array.from(arrayLikeObject));
// This throws TypeError: arrayLikeObject[Symbol.iterator] is not a function
console.log([...arrayLikeObject]);

Wenn Sie nur etwas in ein Array konvertieren möchten, ist es meiner Meinung nach besser, es zu verwenden Array.from() weil es besser lesbar ist. Spread-Elemente sind beispielsweise nützlich, wenn Sie mehrere Arrays verketten möchten (['a', 'b', ...someArray, ...someOtherArray]).

  • Wobei ich dem zustimme Array.from() ist eine äußerst lesbare Möglichkeit, dies zu implementieren, ich fühle, dass die Spread-Element-Syntax ...arrayLikeObject ist für Menschen genauso lesbar (oder noch besser).

    – qarthandso

    21. August 2017 um 0:32 Uhr

  • Beachten Sie auch die Spread-Syntax (...arrayLikeObject) ist viel kürzer. Das kann manchmal ein Faktor sein, obwohl es vielleicht nicht sein sollte.

    – trysis

    6. Juni 2018 um 13:26 Uhr

  • @qarthandso Wenn wir uns in das neue (andere) Array ausbreiten, würde ich zustimmen. Aber wenn wir ein Array duplizieren müssen (in genau dasselbe), dann sieht Array.from attraktiver und zumindest in einigen Fällen besser lesbar aus, dh wenn wir einen Startwert von übergeben müssen Array.prototype.reduce das Array sein, auf dem wir es aufgerufen haben.

    – Eduard

    10. September 2018 um 12:32 Uhr


  • Achtung: Zahlenargumente wie z var i = 5; Array.from(i) ergibt sich [] wohingegen var i = 5; [i] ergibt sich [5]

    – Josh Stodola

    7. August 2019 um 16:08 Uhr


Brunnen, Array.from ist eine statische Methode, dh eine Funktion, während die spread Syntax ist Teil der Array-Literal-Syntax. Sie können Funktionen wie Daten herumreichen, Sie können sie einmal, mehrmals oder gar nicht aufrufen. Das ist mit dem nicht möglich spread Syntax, die in dieser Hinsicht statisch ist.

Ein weiterer Unterschied, auf den @nils bereits hingewiesen hat, ist der Array.from funktioniert auch mit Array-ähnlichen Objekten, die das iterierbare Protokoll nicht implementieren. spread auf der anderen Seite erfordert Iterables.

  • “Array.from funktioniert auch mit Array-ähnlichen Objekten, die das iterierbare Protokoll nicht implementieren” – können Sie ein Beispiel für ein solches Objekt geben?

    – mp

    9. August 2017 um 0:39 Uhr

Benutzer-Avatar
James Donnelly

Der Unterschied besteht darin, dass Spread ein Array zulässt erweitert. Wohingegen from() schafft ein Neu Reihe. .from() erweitert nichts, es erstellt ein neues Array basierend auf den bereitgestellten Daten; Der Spread-Operator hingegen kann ein Array um neue Eigenschaften erweitern.

  • Nun, Array-Literale erzeugen immer a Neu Array auch…

    – Bergi

    11. November 2016 um 12:53 Uhr

  • Ich bin mir nicht sicher, ob ich Ihren Wortlaut nur falsch verstehe, aber schlagen Sie vor, dass der Spread-Operator das Array mutiert, anstatt ein neues zu erstellen?

    – Bergi

    11. November 2016 um 12:55 Uhr

  • @Bergi Nun, der Spread-Operator nicht schaffen eine Anordnung. Die Array-Erstellung im Beispiel von OP erfolgt über die eckigen Klammern, die den Spread-Operator umgeben.

    – James Donnelly

    11. November 2016 um 13:00 Uhr

  • Ah, OK, ich wollte nur sichergehen, dass du das Richtige meinst. Vielleicht würde es helfen, wenn Sie “erweitert das Array-Literal” anstelle von “erweitert ein Array” sagen, da es nicht mit beliebigen Arrays arbeitet.

    – Bergi

    11. November 2016 um 13:03 Uhr

  • Um klarzustellen: Das ...foo Die Syntax verteilt (erweitert) einfach alle Array-Werte, als wären sie separate, durch Kommas getrennte Argumente. Das [] darum herum ERSTELLT sich ein neues Array. So [...foo] erstellt ein neues Array und füllt es, indem alle Array-Elemente so verteilt werden, als wären sie Array-Konstruktor-Argumente, und erstellt eine VOLLSTÄNDIGE KOPIE jedes Elements. Wohingegen Array.from(foo) erstellt ein neues Array mit der Eingabevariablen und ist VIEL SCHNELLER, da es eine FLACHE KOPIE erstellt (dies ist SCHNELLER).

    – Mitch McMabers

    1. Mai 2021 um 22:58 Uhr


Benutzer-Avatar
Amin

Wenn die Eingabe iterierbar ist, tun sie genau dasselbe.

Basierend auf den Benchmarks scheint der Spread-Operator jedoch für ein Set besser abzuschneiden.

https://jsben.ch/5lKjg

let set = new Set();
for (let i = 0; i < 10000; i++) {
  set.add(Math.random());
}


let tArrayFrom = window.performance.now()

let arr = Array.from(set)

console.log("Array.from():", window.performance.now() - tArrayFrom + "ms")


// slightly faster in most of the runs:
let tSpread = window.performance.now()

let arr2 = [...set];

console.log("Spread syntax:", window.performance.now() - tSpread + "ms")

Benutzer-Avatar
Keith

Die Verwendung von Babel ist eine gute Möglichkeit, um zu sehen, was intern passiert.

Aber Kopf hoch. Stellen Sie sicher, dass in Babel das Neueste ausgewählt ist, da die Standardeinstellung falsch ist.

In Ihrem obigen Beispiel ist dies die Ausgabe.

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var spreadDivArray = [].concat(_toConsumableArray(document.querySelectorAll('div')));
console.log(spreadDivArray);

var divArrayFrom = Array.from(document.querySelectorAll('div'));
console.log(divArrayFrom);

  • [].concat scheint nicht zu funktionieren, wenn die Knotenliste nicht concatspreadable ist? Ist das ein Babel-Output?

    – Bergi

    11. November 2016 um 13:04 Uhr

  • Is that a Babel output Tatsächlich habe ich den Code gerade nach babeljs.io kopiert, hast du ein Beispiel? Vielleicht führt babel bei Bedarf andere Transformationen durch. Dies ist natürlich nur ein Test für diesen speziellen Fall.

    – Keith

    11. November 2016 um 13:07 Uhr

  • Das babeljs.io-Repl hat einige seltsame Optionen, es ist nicht wirklich zuverlässig. Verwenden [].concat ist eine falsche Vereinfachung (macht nur dasselbe wie die Spread-Syntax bei Array-Argumenten), die möglicherweise durch einen Fehler in Babel oder eine unbekannte Einstellung verursacht wird.

    – Bergi

    11. November 2016 um 13:11 Uhr

  • Ah, klick latest in babel macht einen unterschied .. ich werde die antwort aktualisieren .. mit neuer ausgabe .. danke für den hinweis.

    – Keith

    11. November 2016 um 13:24 Uhr

  • Ganz zu schweigen davon, dass Sie unterlassen Sie siehe “was intern passiert”, wenn Sie sich den von Babel transpilierten Code ansehen. Was eine Runtime intern tut, ist etwas ganz anderes.

    – Möre

    31. Dezember 2018 um 9:44 Uhr

Benutzer-Avatar
Mitch McMabers

Ich muss die Antworten aller klarstellen:

  • Das ...foo Die Syntax verteilt (erweitert) einfach alle Array-Werte, als wären sie separate, durch Kommas getrennte Argumente. Es macht eine flache Ausbreitung. Alle Primzahlen (Zahlen, Zeichenfolgen usw.) werden KOPIERT und alle komplexen Werte (Objekte) werden stattdessen REFERENZIERT.
  • Das [] darum herum ERSTELLT sich ein neues Array.
  • So [...foo] erstellt ein neues Array und füllt es, indem es eine SHALLOW COPY-Verteilung aller Array-Elemente ausführt, als wären sie Argumente des Array-Konstruktors, die wiederum alle diese kopierten Elemente nehmen und sie in das neue Array einfügen.
  • Wohingegen Array.from(foo) erstellt ein neues Array mit der Eingabevariablen, ist aber VIEL SCHNELLER, weil es NUR eine FLACHE KOPIE erstellt (dies ist SCHNELLER). Es nimmt also die genaue Eingabe und fügt einfach jede Variable/Referenz in das neue Array ein.
  • Verwenden Array.from().

  • [].concat scheint nicht zu funktionieren, wenn die Knotenliste nicht concatspreadable ist? Ist das ein Babel-Output?

    – Bergi

    11. November 2016 um 13:04 Uhr

  • Is that a Babel output Tatsächlich habe ich den Code gerade nach babeljs.io kopiert, hast du ein Beispiel? Vielleicht führt babel bei Bedarf andere Transformationen durch. Dies ist natürlich nur ein Test für diesen speziellen Fall.

    – Keith

    11. November 2016 um 13:07 Uhr

  • Das babeljs.io-Repl hat einige seltsame Optionen, es ist nicht wirklich zuverlässig. Verwenden [].concat ist eine falsche Vereinfachung (macht nur dasselbe wie die Spread-Syntax bei Array-Argumenten), die möglicherweise durch einen Fehler in Babel oder eine unbekannte Einstellung verursacht wird.

    – Bergi

    11. November 2016 um 13:11 Uhr

  • Ah, klick latest in babel macht einen unterschied .. ich werde die antwort aktualisieren .. mit neuer ausgabe .. danke für den hinweis.

    – Keith

    11. November 2016 um 13:24 Uhr

  • Ganz zu schweigen davon, dass Sie unterlassen Sie siehe “was intern passiert”, wenn Sie sich den von Babel transpilierten Code ansehen. Was eine Runtime intern tut, ist etwas ganz anderes.

    – Möre

    31. Dezember 2018 um 9:44 Uhr

1111560cookie-checkArray.from() vs. Spread-Syntax

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy