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
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
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
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.
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")
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
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
11115600cookie-checkArray.from() vs. Spread-Syntaxyes
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 (dhSymbol.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