Iterieren über Eigenschaften in Objekten. JQuery – Iterieren über ein Array, Objekt und Elemente. Javascript iterieren über Elemente in einem assoziativen Array

Es funktioniert so:

// ERFORDERT ECMASCRIPT 2015+ var s, myStringArray = ["Hello", "World"]; for (s of myStringArray) ( // ... etwas mit s machen ... )

Oder noch besser, da ECMAScript 2015 auch blockbezogene Variablen mit let und const bereitstellt:

// ERFORDERT ECMASCRIPT 2015+ const myStringArray = ["Hello", "World"]; for (const s of myStringArray) ( // ... etwas mit s machen ... ) // s ist hier nicht mehr definiert

Ein Hinweis zu Arrays mit geringer Dichte: Ein Array in JavaScript speichert möglicherweise nicht so viele Elemente, wie in seiner Länge angegeben. Diese gemeldete Zahl ist einfach um eins größer als der höchste Index, bei dem der Wert gespeichert ist. Wenn ein Array weniger Elemente enthält, als seine Länge angibt, wird es als dünnbesetzt bezeichnet. Beispielsweise ist es völlig legal, ein Array nur mit Elementen an den Indizes 3, 12 und 247 zu haben; Die Länge eines solchen Arrays wird mit 248 angegeben, obwohl es tatsächlich nur 3 Werte speichert. Wenn Sie versuchen, an einem anderen Index auf das Element zuzugreifen, hat das Array einen undefinierten Wert. Wenn Sie also ein Array „iterieren“ möchten, müssen Sie eine Frage beantworten: Möchten Sie über den gesamten durch seine Länge angegebenen Bereich iterieren und undefinierte Elemente für alle fehlenden Elemente verarbeiten, oder möchten Sie nur die verarbeiten? Elemente tatsächlich vorhanden? Es gibt viele Anwendungen für beide Ansätze; Es kommt nur darauf an, wofür Sie das Array verwenden.

Wenn Sie mit for .. of über ein Array iterieren, wird der Schleifenkörper nach Länge ausgeführt und die Schleifenkontrollvariable wird für alle Elemente, die sich tatsächlich nicht im Array befinden, auf undefiniert gesetzt. Abhängig von den Details Ihres „etwas tun“-Codes könnte dieses Verhalten das sein, was Sie wollen, aber wenn es nicht das ist, was Sie wollen, sollten Sie einen anderen Ansatz wählen.

Natürlich bleibt einigen Entwicklern ohnehin keine andere Wahl, als einen anderen Ansatz zu verwenden, da sie aus irgendeinem Grund auf eine Version von JavaScript abzielen, die noch nicht unterstützt wird für ... von .

Solange Ihre JavaScript-Implementierung mit einer früheren Version der ECMAScript-Spezifikation kompatibel ist (die beispielsweise Versionen von Internet Explorer vor 9 ausschließt), können Sie die Iteratormethode Array#forEach anstelle einer Schleife verwenden. In diesem Fall übergeben Sie eine Funktion, die für jedes Element im Array aufgerufen wird:

Var myStringArray = [ "Hallo", "Welt" ]; myStringArray.forEach(function(s) ( // ... etwas mit s machen ... ));

Im Gegensatz zu for ... of ruft .forEach die Funktion nur für Elemente auf, die tatsächlich Werte enthalten. Wenn wir unser hypothetisches Array mit drei Elementen und einer Länge von 248 übergeben, wird die Funktion nur dreimal aufgerufen, nicht 248 Mal. Außerdem wird zwischen fehlenden Elementen und Elementen unterschieden, die tatsächlich auf undefiniert gesetzt sind. Im letzteren Fall wird die Funktion weiterhin aufgerufen und ein undefinierter Wert als Argument übergeben. Wenn Sie auf diese Weise mit spärlichen Arrays umgehen möchten, ist .forEach möglicherweise die richtige Wahl, auch wenn Ihr Übersetzer for ... of unterstützt.

Die letzte Option, die in allen Versionen von JavaScript funktioniert, ist eine explizite Zählschleife. Sie zählen einfach von 0 bis eins kleiner als die Länge und verwenden den Zähler als Index. Die Hauptschleife sieht so aus:

Ein Vorteil dieses Ansatzes besteht darin, dass Sie wählen können, wie mit spärlichen Arrays umgegangen werden soll. Der obige Code führt den Schleifenkörper über die gesamte Länge aus, wobei s für alle fehlenden Elemente auf undefiniert gesetzt ist, z. B. für .. of . Wenn Sie stattdessen nur tatsächlich vorhandene Elemente eines spärlichen Arrays wie .forEach verarbeiten möchten, können Sie dem Index eine einfache Prüfung hinzufügen:

Var i, s, myStringArray = [ "Hallo", "Welt" ], len = myStringArray.length; für (i=0; i

Das Zuweisen des Längenwerts zu einer lokalen Variablen (im Gegensatz zum Einschließen des vollständigen myStringArray.length-Ausdrucks in die Schleifenbedingung) kann erhebliche Auswirkungen auf die Leistung haben, da die Eigenschaftssuche jedes Mal bis zum Ende übersprungen wird. Wenn ich Rhino auf meinem Computer verwende, beträgt die Geschwindigkeitssteigerung 43 %.

Sie können sehen, dass das Längen-Caching in der Schleifeninitialisierungsklausel wie folgt erfolgt:

Var i, len, myStringArray = [ "Hallo", "Welt" ]; for (len = myStringArray.length, i=0; i

Die von anderen erwähnte for ... in-Syntax wird verwendet, um die Eigenschaften eines Objekts zu durchlaufen. Da ein Array in JavaScript nur ein Objekt mit numerischen Eigenschaftsnamen (und einer automatisch aktualisierten Längeneigenschaft) ist, könnten Sie das Array theoretisch damit in einer Schleife ausführen. Das Problem besteht jedoch darin, dass es nicht auf numerische Eigenschaftswerte beschränkt ist (denken Sie daran, dass selbst Methoden eigentlich nur Eigenschaften sind, deren Wert ein Abschluss ist) und auch nicht garantiert wird, dass sie in numerischer Reihenfolge wiederholt werden. Daher sollte die for ... in-Syntax nicht zum Durchlaufen von Arrays verwendet werden.

22 Antworten

Nachdem dieser Test mit den meisten modernen Browsern durchgeführt wurde ...

Derzeit die schnellste Form einer Schleife (und meiner Meinung nach die syntaktisch offensichtlichste).

Standard für längengespeicherte Schleife

Für (var i = 0, len = myArray.length; i< len; i++) { }

Ich würde sagen, dass dies definitiv ein Fall ist, in dem ich den Entwicklern von JavaScript-Engines applaudiere. Die Ausführungszeit sollte optimiert werden Klarheit, nicht aus Bequemlichkeit.

Stand Juni 2016, mehrere Tests im neuesten Chrome (71 % des Browsermarktes im Mai 2016, Tendenz steigend):

  • Der schnellste Zyklus ist der Schleifenzyklus, sowohl mit als auch ohne Cache-Länge, was eine sehr ähnliche Leistung bietet. (Eine for-Schleife mit einer zwischengespeicherten Länge liefert manchmal bessere Ergebnisse als eine, die nicht zwischengespeichert ist, aber der Unterschied ist nahezu vernachlässigbar, was bedeutet, dass die Engine möglicherweise zugunsten der standardmäßigen und vielleicht einfachsten Schleife ohne Cache optimiert wird.)
  • Die while-Schleife mit Dekrementen war etwa 1,5-mal langsamer als die for-Schleife.
  • Eine Schleife mit einer Callback-Funktion (z. B. Standard forEach) war etwa zehnmal langsamer als eine for-Schleife.

Ich glaube, dieser Thread ist zu alt und Programmierer haben das Gefühl, sie müssten die Länge zwischenspeichern oder Schnittpunkte mit rückwärtiger Verringerung verwenden, um eine bessere Leistung zu erzielen und Code zu schreiben, der weniger wählerisch und fehleranfälliger ist als nur eine einfache for-Schleife. Deshalb empfehle ich:

    Wenn Ihre Anwendung viele Elemente durchläuft oder sich Ihr Schleifencode in einer Funktion befindet, die häufig verwendet wird, ist eine gerade Schleife die Antwort:

    Für (var i = 0; i< arr.length; i++) { // Do stuff with arr[i] or i }

    Wenn Ihre Anwendung nicht wirklich über viele Elemente iteriert oder Sie nur hier und da kleine Iterationen durchführen müssen, ist die Verwendung des standardmäßigen forEach-Rückrufs oder einer ähnlichen Funktion aus der JS-Bibliothek Ihrer Wahl möglicherweise sauberer und weniger fehleranfällig als der Index Der Variablenbereich ist privat und Sie müssen keine Klammern verwenden, die direkt auf den Array-Wert zugreifen:

    Arr.forEach(function(value, index) ( // Sachen mit Wert oder Index machen ));

    Wenn Sie beim Durchlaufen von Milliarden von Zeilen wirklich ein paar Millisekunden verarbeiten müssen und sich die Länge des Arrays dabei nicht ändert, können Sie die Länge in einer for-Schleife zwischenspeichern. Obwohl ich denke, dass es heutzutage wirklich nicht mehr nötig ist:

    Für (var i = 0, len = arr.length; i< len; i++) { // Do stuff with arr[i] }

Es ist erst 2018, also könnte ein Update gut sein ...

Und das sollte ich wirklich stimme der akzeptierten Antwort nicht zu. Es hängt von verschiedenen Browsern ab. Manche machen forEach schneller, manche for-Schleife und manche while testet alle Methoden http://jsben.ch/mW36e

Arr.forEach(a => ( // ... )

und da man viele for(a = 0;...)-Schleifen wie for(a = 0;...) sehen kann, ist es erwähnenswert, dass „var“ ohne Variablen global definiert wird und dies erhebliche Auswirkungen haben kann Geschwindigkeit, also wird es langsam sein.

var arr = arr = new Array(11111111).fill(255); var benches = [ [ "empty", () =>< l; a++); }] , ["for-loop", () =>( for(var a = 0, l = arr.length; a< l; ++a) var b = arr[a] + 1; }] , ["for-loop++", () =>( for(var a = 0, l = arr.length; a< l; a++) var b = arr[a] + 1; }] , ["for-loop - arr.length", () =>( for(var a = 0; a< arr.length; ++a) var b = arr[a] + 1; }] , ["reverse for-loop", () =>( for(var a = arr.length - 1; a >= 0; --a) var b = arr[a] + 1; )] ,["while-loop", () => ( var a = 0 , l = arr.length; while(a< l) { var b = arr[a] + 1; ++a; } }] , ["reverse-do-while-loop", () =>( var a = arr.length - 1; // VORSICHT do ( var b = arr[a] + 1; ) while(a--); )] , ["forEach", () => ( arr.forEach( a => ( var b = a + 1; )); ["for..in (only 3.3%)", () => ( var ar = arr.slice(0,arr.length/33) ; for( const a in ar) ( var b = a + 1; )] , ["Duff device", () => ( var i = 0; var r = arr.length % 8; var n = (arr .length - r ) / 8; if (r > 0) do ( var b = arr + 1; ) while (--r); if (n > 0) do ( var b = arr[i] + 1; var c = arr + 1; var e = arr + 1; --n >>> 3;] , ["Duff device negative", () => ( var r = arr.length % 8; var n = (arr.length-r) / 8 ; ///Math.floor(arr.length ; // -1; arr[--i] + 1; --r; ) while (n)( var b = arr[i] + 1; var c = arr + 1; var e = arr + 1; var f = arr + 1; var h = arr + 1; var j = arr + 1; function bench(title, f) ( var t0 = performance.now(); var res = f(); return performance.now() - t0; // console.log("$(title) take $(t1-t0 ) msec"); ) var globalVarTime = bench("for-loop without "var"", () => ( // Wenn Sie hier vergessen, "var" einzugeben, sind die Variablen global for(a = 0, l = arr.length;< l; ++a) var b = arr[a] + 1; }); var times = benches.map(function(a) { arr = new Array(11111111).fill(255); return }).sort((a,b) =>a-b); var max = mal; times = times.map(a => (a = (a/max)*100; return a; )); var template = (Titel, Zeit, n) => "

" + "$(title) " + " $(Number(time.toFixed(3)))msec" + "
"; var strRes = times.map(t => template(...t)).join("\n") + "

for-Schleife ohne „var“ $(globalVarTime) msec.“; var $container = document.getElementById(“container“); $container.innerHTML = strRes; body ( color:#fff; Hintergrund:#333; Schriftfamilie :helvetica; ) body > div > div ( clear:both ) body > div > div > span ( float:left; width:43%; margin:3px 0; text-align:right; ) body > div > div > span :nth-child(2) ( text-align:left; background:darkorange; animation:showup .37s .111s; -webkit-animation:showup .37s .111s; ) @keyframes showup ( from ( width:0; ) ) @-webkit-keyframes showup ( from ( width:0; ) )

2014 Vor einiger Zeit

Denk logisch.

Schau dir das an

For(var index = 0 , length = array.length ; index< length ; index++) { //do stuff }

  • Sie müssen mindestens 2 Variablen erstellen (Index, Länge)
  • Es muss überprüft werden, ob der Längenindikator kleiner ist als
  • Der Index muss erhöht werden
  • Die for-Schleife hat 3 Parameter

Sagen Sie mir jetzt, warum das schneller sein sollte als:

Var-Länge = array.length; while(--length) ( //oder length-- //Sachen machen)

  • Eine Variable
  • Keine Schecks
  • Index sinkt (Maschinen bevorzugen dies)
  • While hat nur einen Parameter

Ich war völlig verwirrt, als Chrome 28 zeigte, dass die for-Schleife schneller als die Zeit war. Es sollte so etwas sein

„Nun, jeder verwendet eine for-Schleife. Konzentrieren wir uns darauf, wenn es um Chrome geht.“

Aber jetzt, im Jahr 2014, kehrt die While-Schleife zu Chrome zurück. Es ist 2x schneller, in anderen/alten Browsern war es immer schneller.

Ich habe in letzter Zeit einige neue Tests durchgeführt. In der realen Umgebung sind diese Shortcodes nun wertlos und jsperf kann die while-Schleife nicht richtig ausführen, da array.length neu erstellt werden muss, was ebenfalls Zeit kostet.

Die tatsächliche Geschwindigkeit der while-Schleife auf jsperf kann NICHT ermittelt werden.

Sie müssen Ihre eigene Funktion erstellen und dies mit window.performance.now() überprüfen

Und ja ... es gibt keine Möglichkeit, eine While-Schleife schneller zu machen.

Das eigentliche Problem ist die tatsächliche Manipulations-/Wiedergabezeit/Zeichnungszeit oder wie auch immer Sie es nennen möchten.

Ich habe zum Beispiel eine Canvas-Szene, in der ich Koordinaten und Kollisionen berechnen muss ... dies geschieht in 10–200 Mikrosekunden (nicht in Millisekunden). Tatsächlich dauert es mehrere Millisekunden, um alles zu erledigen. Dasselbe wie in DOM.

In einigen Fällen gibt es noch eine weitere äußerst effiziente Möglichkeit, Schleifen zu verwenden, beispielsweise zum Kopieren/Klonen eines Arrays

For(var i = array.length; i > 0; arrayCopy[ --i ] = array[ i ] // Dinge tun);

Bitte beachten Sie die Parametereinstellungen:

  • Das Gleiche wie in der while-Schleife. Ich verwende nur eine Variable
  • Es muss überprüft werden, ob der Index größer als 0 ist.
  • Wie Sie sehen können, unterscheidet sich dieser Ansatz von der üblichen Schleife, die jeder verwendet, da ich Dinge innerhalb des dritten Parameters mache und auch direkt innerhalb des Arrays dekrementiere.

Es wird gesagt, dass dies bestätigt, dass Maschinen wie

schrieb, dass ich daran dachte, es etwas kürzer zu machen und einige unnötige Dinge zu entfernen, und schrieb dieses im gleichen Stil:

For(var i = array.length ; i-- ; arrayCopy[ i ] = array[ i ] // Dinge tun);

Auch wenn es kürzer ist, scheint es, als würde die Verwendung von i alles noch einmal verlangsamen. Dies ist 1/5 langsamer als die vorherige for- und while-Schleife.

Notiz:; sehr wichtig nach dem Klo ohne ()

Auch wenn ich Ihnen gerade gesagt habe, dass jsperf nicht der beste Weg ist, Skripte zu testen. Ich habe hier 2 Schleifen hinzugefügt.

Und hier ist eine weitere Antwort zur Leistung in Javascript

Diese Antwort sollte leistungsstarke Möglichkeiten zum Schreiben von Javascript zeigen. Wenn Sie dies also nicht lesen können, fragen Sie und Sie erhalten eine Antwort oder lesen ein Buch über Javascript http://www.ecma-international.org/ecma-262/5.1/

Die neueste Überarbeitung des Tests, den ich vorbereitet habe (durch Wiederverwendung eines älteren), zeigt eines.

Die Cache-Länge ist nicht so wichtig, schadet aber nicht.

Jeder erste Lauf des oben verlinkten Tests (im neu geöffneten Tab) liefert die besten Ergebnisse für die letzten 4 Fragmente (3., 5., 7. und 10. in den Diagrammen) in Chrome, Opera und Firefox auf meinem 64-Bit-Debian Squeeze ( meiner Desktop-Hardware). Nachfolgende Läufe ergeben ein völlig anderes Ergebnis.

Die Schlussfolgerungen zur Leistung sind einfach:

  • Gehen Sie in eine for-Schleife (vorwärts) und prüfen Sie stattdessen mit !==< .
  • Wenn Sie das Array später nicht wiederverwenden müssen, ist auch eine Schleife mit reduzierter Länge und destruktivem Array-shift() -ing effektiv.

Derzeit (2011.10) scheint die folgende Vorlage die schnellste zu sein.

For (var i = 0, len = arr.length; i !== len; i++) ( ... )

Denken Sie daran, dass das Zwischenspeichern von arr.length hier nicht entscheidend ist. Sie können also einfach i !== arr.length testen und es wird keine Leistungseinbußen geben, aber Sie erhalten kürzeren Code.

PS: Ich weiß, dass in einem Fragment mit Shift() dessen Ergebnis verwendet werden kann, anstatt auf das 0. Element zuzugreifen, aber ich habe das irgendwie übersehen, nachdem ich die vorherige Revision wiederverwendet habe (die während Schleifen den falschen Wert hatte), und später habe ich es nicht getan Ich möchte die bereits erzielten Ergebnisse verlieren.

„Am besten“ im Sinne purer Leistung? oder Leistung UND?

Die rein „beste“ Leistung ist diejenige, die den Cache und den ++-Präfixoperator verwendet (meine Daten: http://jsperf.com/caching-array-length/189).

Für (var i = 0, len = myArray.length; i< len; ++i) { // blah blah }

Ich würde sagen, eine Schleife ohne Cache ist das beste Gleichgewicht zwischen Ausführungszeit und Lesezeit des Programmierers. Jeder Programmierer, der mit C/C++/Java beginnt, wird keine ms ausgeben, um dies zu lesen

For(var i=0; i< arr.length; i++){ // blah blah }

** Die Länge des Arrays innerhalb der Schleife zwischenspeichern, dadurch gehen einige Sekunden Zeit verloren. Hängt von den Elementen im Array ab. Wenn das Array mehr Elemente enthält, gibt es einen großen Unterschied hinsichtlich der Ms-Zeit*

SArr; //Array; for(var i = 0 ; i

SArr; //Array; for(var i = 0,len = sArr.length ; i< len ; i++) { callArray(sArr[i]); //function call } ***end: 1.354ms***

Dies ist das Jahr 2017 .

Ich habe einige Tests durchgeführt.

Es sieht so aus, als ob die while-Methode in Chrome die schnellste ist.

Es sieht so aus, als ob das linke Dekrement (--i) viel schneller ist als die anderen (++i, i--, i++) in Firefox.

Dieser Ansatz entspricht im Durchschnitt dem Fasten. Aber es iteriert das Array in umgekehrter Reihenfolge.

Sei i = array.length; while (--i >= 0) ( doSomething(array[i]); )

Wenn die Prioritätsreihenfolge wichtig ist, verwenden Sie diesen Ansatz.

Sei ii = array.length; sei i = 0; während ich< ii) { doSomething(array[i]); ++i; }

Ich schreibe immer im ersten Stil.

Selbst wenn der Compiler intelligent genug ist, um ihn für Arrays zu optimieren, ist er dennoch intelligent, wenn wir hier DOMNodeList oder ein komplexes Objekt mit berechneter Länge verwenden?

Ich weiß, dass es bei der Frage um Arrays geht, aber ich denke, es ist eine gute Praxis, alle Ihre Schleifen im gleichen Stil zu schreiben.

Var arr = ; // Das Array var i = 0; während ich< arr.length) { // Do something with arr[i] i++; }

i++ ist schneller als ++i, --i und i -

Guten Tag! In der letzten Lektion haben wir uns angeschaut, was Objekte sind und warum sie benötigt werden. Heute schauen wir uns an, wie man mit den Eigenschaften eines Objekts arbeitet und wie man alle diese Eigenschaften tatsächlich sortiert. Für diese Zwecke wird eine for..in-Eigenschaftsschleife verwendet (Sie können mehr über Schleifen in JavaScript erfahren).

Schleife für..in

Syntax:

For (obj eingeben) ( /* ... Aktionen mit obj ... */ )

Die for..in-Schleife durchläuft nacheinander die Eigenschaften des obj-Objekts und schreibt den Namen jeder Eigenschaft in den Schlüssel.

Deklarieren einer Variablen in einer for-Schleife (var-Schlüssel in obj)

In dieser Schleife können Sie die Schlüsselvariable deklarieren:

For (Var-Taste in Menü1) ( // ... )

Schauen wir uns ein Beispiel für das Durchlaufen der Eigenschaften eines Objekts mithilfe einer for...in-Schleife an:

Var menu = (width: 400, height: 300, title: „Menu My“ ); for (var key in menu) ( // dieser Code funktioniert für jede Eigenschaft des Objekts // ..und zeigt den Eigenschaftsnamen und seinen Wert entsprechend an warning("Key: " + key + " value: " + menu) ; )

Ich möchte Sie darauf aufmerksam machen, dass wir im Beispiel das Menü mit eckigen Klammern verwendet haben. Denn wenn wir den Namen einer Eigenschaft in einer Variablen speichern, können wir nur über eckige Klammern darauf zugreifen, nicht jedoch über einen Punkt.

Schleife für…von

Außerdem gibt es eine neue Schleife zum Durchlaufen von Objekten und Arrays. Ihre Syntax ist der for...in-Schleife sehr ähnlich, der Unterschied besteht jedoch darin, dass sie nicht die Schlüssel oder Indizes des Arrays ausgibt, sondern dessen Werte. Hier ist ein Beispiel:

Var menu = (width: 400, height: 300, title: „Menu My“ ); for (var key of menu) ( // dieser Code funktioniert für jede Eigenschaft des Objekts // ..und zeigt den Eigenschaftswert entsprechend an warning("value: " + key +","); //400, 300, „Menü Mein“ )

Anzahl der Eigenschaften in einem Objekt

Aber was ist, wenn Sie die Anzahl der Eigenschaften in einem Objekt wissen müssen? Wie kann ich das machen?

Leider gibt es für dieses Problem keine fertigen Lösungen.

Am einfachsten ist es, die Eigenschaften zu durchlaufen und wie folgt zu berechnen:

Var menu = (width: 400, height: 300, title: „Menu My“ ); Var-Anzahl = 0; for (Var-Taste im Menü) ( count++; ) alarm("Gesamteigenschaften: " + count);

Ergebnisse

  • Um die Eigenschaften eines Objekts zu durchlaufen, wird eine Schlüsselschleife verwendet: for (key in obj).

Aufgaben

Stellen Sie fest, ob ein Objekt leer ist

Erstellen Sie eine Funktion isEmptyObject(obj), die true zurückgibt, wenn das Objekt keine Eigenschaften hat, und false, wenn mindestens eine Eigenschaft vorhanden ist.

Es sollte so funktionieren:

Funktion isEmptyObject(obj) ( /* Ihr Code */ ) var obj = (); alarm(isEmptyObject(obj)); // true obj["8:30"] = "rise"; alarm(isEmptyObject(obj)); // FALSCH

Berechnen Sie das arithmetische Mittel aller Objekteigenschaften

Es gibt ein Gehaltsobjekt mit Gehältern. Schreiben Sie einen Code, der den arithmetischen Durchschnitt aller Gehälter anzeigt.
Wenn das Objekt leer ist, sollte das Ergebnis 0 sein.
Zum Beispiel.

Guten Tag! Wir beschäftigen uns weiterhin mit Array-Methoden und werden uns in dieser Lektion mit Methoden zum Durchlaufen eines Arrays befassen. Mit diesen Methoden können Sie ein Array durchlaufen und bestimmte Aktionen für seine Elemente ausführen. Ja, ich habe vergessen zu erwähnen, dass alle diese Methoden in IE 8 nicht unterstützt werden. Obwohl es jetzt so wichtig ist, dass sie von diesem Browser nicht unterstützt werden, wird Ihnen ES5-shim dennoch helfen, wenn Sie IE8-Unterstützung wünschen. Und wir werden weitermachen

forEach-Methode

Diese Methode wird verwendet, um ein Array in einer Schleife zu durchlaufen. Sie können ihr jedoch auch eine Funktion übergeben, mit der Sie bestimmte Aktionen für die Elemente des Arrays ausführen können. Schauen wir uns ein Beispiel an.

Var mas = [„Banane“, „Avocado“, „Karotte“]; mas.forEach(function(item, i, mas) ( alarm(i + ": " + item + " (array: " + mas + ")"); ));

Hier im Beispiel wird eine Funktion an die forEach-Methode übergeben, die 3 Parameter angibt:

Artikel- Array-Element

ich— Nummer des Array-Elements

mas– das Array, das verarbeitet wird.

Diese Methode kann anstelle einer for-Schleife verwendet werden, um ein Array zu durchlaufen.

Filtermethode

Diese Methode wird wie die forEach-Methode zum Durchlaufen eines Arrays verwendet und erhält eine Funktion als Argument. Sie ermöglicht jedoch das Filtern des Arrays und gibt ein neues Array zurück, das nur die Elemente enthält, für die die von uns übergebene Funktion gilt Diese Methode gibt true zurück.

Es ist etwas verwirrend, also schauen wir es uns anhand eines Beispiels an.

Var mas = ; var positiveNum = mas.filter(function(num) ( return num > 0; )); document.write(positiveNum); // 1,4,3

Im Beispiel gibt es ein Array mit Zahlen und wir müssen ein weiteres Array erhalten, das nur positive Zahlen aus dem ursprünglichen Array enthalten würde. Dazu wenden wir die Filtermethode auf das Array an und rufen eine Funktion auf, die jedes Element prüft, das heißt, sie gibt alle positiven Zahlen zurück und das Ergebnis wird in einem anderen Array gespeichert, im Beispiel ist dies positiveNum.

Kartenmethode

Die Map-Methode erstellt ein weiteres Array, das aus den Ergebnissen des Aufrufs der Funktion des ursprünglichen Arrays besteht. In dieser Funktion werden jedoch einige Aktionen für die Elemente des ursprünglichen Arrays ausgeführt, und das Ergebnis wird unverändert im neuen Array angezeigt. Schauen wir uns ein Beispiel an, sonst ist es meiner Meinung nach völlig unklar.

Var mas = ; var newMas = mas.map(function(item) ( return item*item; )); // Habe ein Array mit Quadraten erhalten alarm(newMas); // 1,4,9

Im Beispiel gibt es ein Ausgangsarray mit Zahlen, darauf wird die Map-Methode angewendet, bei der jedes Element des Arrays mit sich selbst multipliziert und das Ergebnis in ein anderes Array geschrieben wird. Als Ergebnis erhalten wir ein Array mit den Quadraten der Zahlen im ursprünglichen Array.

Methoden alle/einige

Diese Methoden prüfen, ob ein Element im Array vorhanden ist. Sie tun dies über eine Funktion, die ihnen als Parameter übergeben wird. Das heißt, wenn diese Funktion „true“ zurückgibt, gibt die Methode selbst „true“ zurück. Darüber hinaus erfordert die Methode every, dass jedes Element die Bedingung der Funktion erfüllt, und die Methode some erfordert, dass mindestens eine Übereinstimmung vorliegt. Und wie immer gibt es hier ein Beispiel für Sie.

Var mas = ; function isPositiv(num) ( return num > 0; ) if(mas.every(isPositiv)) ( document.write("Das Array enthält nur positive Zahlen"); ) else( document.write("Das Array enthält mindestens eine negative Zahl "); ) if(mas.some(isPositiv)) ( document.write("Das Array enthält mindestens eine positive Zahl"); ) else ( document.write("Es gibt keine positiven Zahlen im Array") ; )

Betrachten Sie ein Beispiel: Wir haben ein Array mit positiven und negativen Zahlen und müssen es auf das Vorhandensein mindestens einer negativen Zahl überprüfen. Dazu nutzen wir die every- und some-Methoden. Wir erstellen eine Funktion, die positive Zahlen zurückgibt, und übergeben sie dann an die Methode every. Da diese Methode ein logisches Ergebnis zurückgibt, wird sie in bedingten Anweisungen verwendet. Die every-Methode in unserem Beispiel gibt „false“ zurück, weil das Array negative Zahlen enthält, die some-Methode gibt jedoch „true“ zurück, weil das Array mindestens eine positive Zahl enthält.

reduzieren/reduceRight

Wenn Sie ein Array durchlaufen müssen, können Sie forEach, for oder for..of verwenden.

Wenn Sie ein Array durchlaufen und Daten für jedes Element zurückgeben müssen, verwenden Sie Map.

Methoden arr.reduzieren Und arr.reduceRightÄhnlich den oben genannten Methoden, jedoch etwas komplizierter. Sie werden verwendet, um einen einzelnen Wert basierend auf dem gesamten Array zu berechnen.

Syntax:

Let value = arr.reduce(function( previousValue, item, index, array) ( // ... ), );

Die Funktion wird der Reihe nach auf alle Elemente des Arrays angewendet und „übernimmt“ ihr Ergebnis beim nächsten Aufruf.

Argumente:

  • previousValue – das Ergebnis des vorherigen Aufrufs dieser Funktion, gleich initial beim ersten Aufruf (falls initial übergeben wird),
  • item – das nächste Element des Arrays,
  • index – sein Index,
  • Array – das Array selbst.

Wenn eine Funktion aufgerufen wird, wird das Ergebnis ihres Aufrufs für das vorherige Element des Arrays als erstes Argument übergeben.

Das klingt kompliziert, wird aber einfacher, wenn Sie sich das erste Argument als „Akkumulierung“ des Ergebnisses früherer Funktionsaufrufe vorstellen. Wenn es fertig ist, wird es das Ergebnis von Reduzieren.

Diese Methode lässt sich wie immer am einfachsten anhand eines Beispiels verstehen.

Hier erhalten wir die Summe aller Array-Elemente in nur einer Zeile:

Sei arr = ; let result = arr.reduce((sum, current) => sum + current, 0); Warnung(Ergebnis); // 15

Hier haben wir die häufigste Reduzierungsoption verwendet, die nur zwei Argumente verwendet.

Schauen wir uns die Funktionsweise genauer an.

  1. Beim ersten Durchlauf ist sum initial (das letzte Argument von Reduce), also 0, und current ist das erste Element des Arrays, also 1. Somit ist das Ergebnis der Funktion 1.
  2. Wenn wir sum = 1 zum zweiten Mal ausführen, fügen wir das zweite Element des Arrays (2) hinzu.
  3. Beim dritten Durchlauf ist sum = 3, zu dem wir das nächste Element hinzufügen und so weiter ...

Der Berechnungsablauf sieht folgendermaßen aus:

In Form einer Tabelle, wobei jede Zeile ein Funktionsaufruf für das nächste Element des Arrays ist:

Summe aktuell Ergebnis
erster Aufruf 1 1
zweiter Anruf 1 2 3
dritte Herausforderung 3 3 6
vierte Herausforderung 6 4 10
fünfte Herausforderung 10 5 15

Hier sieht man deutlich, wie das Ergebnis des vorherigen Aufrufs in das erste Argument des nächsten Aufrufs übergeben wird.

Wir können den Anfangswert auch weglassen:

Sei arr = ; // der Anfangswert wird entfernt (keine 0 am Ende) let result = arr.reduce((sum, current) => sum + current); Warnung(Ergebnis); // 15

Das Ergebnis ist genau das gleiche! Dies liegt daran, dass beim Fehlen von „initial“ das erste Element des Arrays als erster Wert verwendet wird und die Suche beim zweiten beginnt.

Die Berechnungstabelle ist bis auf die erste Zeile dieselbe.

Eine solche Verwendung erfordert jedoch äußerste Vorsicht. Wenn das Array leer ist, führt der Aufruf von Reduce ohne Anfangswert zu einem Fehler.

Hier ist ein Beispiel:

Sei arr = ; // Fehler: Reduzieren eines leeren Arrays ohne Anfangswert // Wenn es einen Anfangswert gäbe, würde Reduzieren ihn für ein leeres Array zurückgeben. arr.reduce((sum, current) => sum + current);

Ergebnisse

Zusammenfassend haben wir uns verschiedene Methoden zum Arbeiten mit Arrays in einer Schleife angesehen. Alle diese Methoden haben eines gemeinsam: Sie müssen alle eine Funktion als Argument übergeben.

  • forEach – zum Durchlaufen eines Arrays.
  • Filter – um das Array zu filtern. Gibt ein neues gefiltertes Array zurück
  • every/some – um das Array auf das Vorhandensein einzelner Elemente zu überprüfen.
  • Karte – um ein Array in ein Array umzuwandeln. Gibt das ursprünglich konvertierte Array zurück.
  • reduce/reduceRight – Berechnet einen Wert aus dem gesamten Array, ruft für jedes Element eine Funktion auf und übergibt das Zwischenergebnis zwischen den Aufrufen. Kann zur Berechnung der Summe von Array-Elementen verwendet werden.

Aufgaben

Holen Sie sich ein neues Array

Wenn das Array var mas = ["HTML", "CSS", "JavaScript", "Pascal"] gegeben ist, müssen Sie die Map-Methode verwenden, um ein neues Array zu erhalten, das die Längen jedes Elements des ursprünglichen Arrays enthält .

Filtern Sie das Array

Es gibt ein Array var mas = Sie müssen die Filtermethode verwenden, um ein Array zu erhalten, das nur positive Zahlen enthält.

Array prüfen

Es gibt ein Array var mas = Sie müssen prüfen, ob das Array negative Zahlen enthält, und das Ergebnis auf dem Bildschirm anzeigen.

Nun, zum Schluss noch ein kurzes Video über Methoden zum Durchlaufen eines Arrays.

  • I. Iterieren über reale Arrays
    1. forEach-Methode und verwandte Methoden
    2. for-Schleife
    3. Richtige Verwendung der for...in-Schleife
    4. for...of-Schleife (implizite Verwendung des Iterators)
    5. Explizite Verwendung des Iterators
  • II. Iterieren über Array-ähnliche Objekte
    1. Verwenden von Methoden zum Durchlaufen realer Arrays
    2. In ein echtes Array konvertieren
    3. Ein Hinweis zu Laufzeitobjekten

I. Iterieren über reale Arrays

Derzeit gibt es drei Möglichkeiten, die Elemente eines realen Arrays zu durchlaufen:

  1. Methode Array.prototype.forEach ;
  2. klassische for-Schleife
  3. eine „richtig“ konstruierte for...in-Schleife.

Darüber hinaus werden mit der Einführung des neuen Standards ECMAScript 6 (ES 6) bald zwei weitere Methoden erwartet:

  1. for...of-Schleife (implizite Verwendung des Iterators);
  2. explizite Verwendung von Iteratoren.

1. Die forEach-Methode und verwandte Methoden

Wenn Ihr Projekt die Funktionen des ECMAScript 5 (ES5)-Standards unterstützen soll, können Sie eine seiner Innovationen verwenden – die forEach-Methode.

Anwendungsbeispiel:

Var a = ["a", "b", "c"]; a.forEach(function(entry) ( console.log(entry); ));

Im Allgemeinen erfordert die Verwendung von forEach eine Verbindung mit der Emulationsbibliothek es5-shim für Browser, die diese Methode nicht nativ unterstützen. Dazu gehören IE 8 und früher, die mancherorts noch im Einsatz sind.

Der Vorteil von forEach besteht darin, dass keine lokalen Variablen zum Speichern des Index und des Werts des aktuellen Array-Elements deklariert werden müssen, da diese automatisch als Argumente an die Rückruffunktion übergeben werden.

Wenn Sie sich Sorgen über die möglichen Kosten für einen Rückruf für jedes Element machen, machen Sie sich keine Sorgen und lesen Sie dies.

forEach ist darauf ausgelegt, alle Elemente eines Arrays zu durchlaufen, aber darüber hinaus bietet ES5 mehrere weitere nützliche Methoden zum Durchlaufen aller oder einiger Elemente sowie zum Ausführen einiger Aktionen an ihnen:

  • every – gibt true zurück, wenn der Callback für jedes Element des Arrays einen Wert zurückgibt, der in true konvertiert werden kann.
  • some – gibt „true“ zurück, wenn der Rückruf für mindestens ein Element des Arrays einen Wert zurückgibt, der in „true“ konvertiert werden kann.
  • filter – erstellt ein neues Array, das die Elemente des ursprünglichen Arrays enthält, für die der Rückruf true zurückgibt.
  • Karte – erstellt ein neues Array bestehend aus den vom Rückruf zurückgegebenen Werten.
  • Reduzieren – Reduziert ein Array auf einen einzelnen Wert und wendet nacheinander einen Rückruf auf jedes Element des Arrays an, beginnend mit dem ersten (kann nützlich sein, um die Summe von Array-Elementen und anderen Zusammenfassungsfunktionen zu berechnen).
  • ReduceRight – funktioniert ähnlich wie Reduce, durchläuft die Elemente jedoch in umgekehrter Reihenfolge.

2. For-Schleife

Gute alte Regeln:

Var a = ["a", "b", "c"]; Var-Index; für (Index = 0; Index< a.length; ++index) { console.log(a); }

Wenn die Länge des Arrays während der gesamten Schleife konstant ist und die Schleife selbst zu einem leistungskritischen Codeabschnitt gehört (was unwahrscheinlich ist), können Sie eine „optimalere“ Version von for verwenden, die die Länge des Arrays speichert :

Var a = ["a", "b", "c"]; var index, len; for (index = 0, len = a.length; index< len; ++index) { console.log(a); }

Theoretisch sollte dieser Code etwas schneller laufen als der vorherige.

Wenn die Reihenfolge der Elemente nicht wichtig ist, können Sie im Hinblick auf die Optimierung sogar noch weiter gehen und die Variable zum Speichern der Länge des Arrays entfernen und die Reihenfolge der Suche in das Gegenteil ändern:

Var a = ["a", "b", "c"]; Var-Index; for (index = a.length - 1; index >= 0; --index) ( console.log(a); )

In modernen JavaScript-Engines bedeuten solche Optimierungsspiele jedoch meist nichts.

3. Korrekte Verwendung der for...in-Schleife

Wenn Ihnen die Verwendung einer for...in-Schleife empfohlen wird, denken Sie daran, dass die Iteration über Arrays nicht der Zweck ist, für den sie gedacht ist. Entgegen einem weit verbreiteten Missverständnis iteriert die for...in-Schleife nicht über Array-Indizes, sondern durch aufzählbare Eigenschaften eines Objekts.

In manchen Fällen, beispielsweise bei der Iteration über Arrays mit geringer Dichte, kann for...in jedoch nützlich sein, sofern Sie Vorsichtsmaßnahmen treffen, wie im folgenden Beispiel gezeigt:

// a - Sparse-Array var a = ; a = „a“; a = „b“; a = „c“; for (var key in a) ( if (a.hasOwnProperty(key) && /^0$|^d*$/.test(key) && key<= 4294967294) { console.log(a); } }

In diesem Beispiel werden bei jeder Iteration der Schleife zwei Prüfungen durchgeführt:

  1. dass das Array eine eigene Eigenschaft namens Schlüssel hat (nicht von seinem Prototyp geerbt).
  2. Dieser Schlüssel ist eine Zeichenfolge, die die Dezimaldarstellung einer Ganzzahl enthält, deren Wert kleiner als 4294967294 ist. Woher kommt die letzte Zahl? Aus der Definition eines Array-Index in ES5, die zeigt, dass der höchste Index, den ein Element in einem Array haben kann, ist: (2^32 - 2) = 4294967294 .

Natürlich nehmen solche Prüfungen beim Ausführen der Schleife unnötig Zeit in Anspruch. Im Fall eines Sparse-Arrays ist diese Methode jedoch effizienter als eine for-Schleife, da in diesem Fall nur diejenigen Elemente iteriert werden, die explizit im Array definiert sind. Im obigen Beispiel werden also nur 3 Iterationen durchgeführt (für die Indizes 0, 10 und 10000) – im Vergleich zu 10001 in der for-Schleife.

Um nicht jedes Mal, wenn Sie ein Array durchlaufen müssen, einen so umständlichen Prüfcode zu schreiben, können Sie ihn als separate Funktion schreiben:

Funktion arrayHasOwnIndex(array, key) ( return array.hasOwnProperty(key) && /^0$|^d*$/.test(key) && key<= 4294967294; }

Dann wird der Schleifenkörper aus dem Beispiel deutlich reduziert:

For (key in a) ( if (arrayHasOwnIndex(a, key)) ( console.log(a); ) )

Der oben besprochene Prüfcode ist universell und für alle Fälle geeignet. Stattdessen können Sie aber auch eine kürzere Version verwenden, die zwar formal nicht ganz korrekt, aber dennoch für die meisten Fälle geeignet ist:

For (key in a) ( if (a.hasOwnProperty(key) && String(parseInt(key, 10)) === key) ( console.log(a); ) )

4. For...of-Schleife (implizite Verwendung des Iterators)

ES6, noch im Entwurfsstatus, sollte Iteratoren in JavaScript einführen.

Iterator ist ein von einem Objekt implementiertes Protokoll, das eine Standardmethode zum Erhalten einer Folge von Werten (endlich oder unendlich) definiert.
Ein Objekt verfügt über einen Iterator, wenn es eine next()-Methode definiert, eine Funktion ohne Argumente, die ein Objekt mit zwei Eigenschaften zurückgibt:

  1. done (boolean) – wahr, wenn der Iterator das Ende der iterierbaren Sequenz erreicht hat. Andernfalls ist der Wert false .
  2. Wert – definiert den vom Iterator zurückgegebenen Wert. Kann undefiniert (fehlend) sein, wenn die done-Eigenschaft true ist.

Viele eingebaute Objekte, inkl. Echte Arrays verfügen standardmäßig über Iteratoren. Der einfachste Weg, einen Iterator für echte Arrays zu verwenden, ist die Verwendung des neuen for...of-Konstrukts.

Beispiel für die Verwendung von for...of:

Varval; var a = ["a", "b", "c"]; for (Wert von a) ( console.log(val); )

Im obigen Beispiel ruft die for...of-Schleife implizit den Iterator des Array-Objekts auf, um jeden Wert des Arrays abzurufen.

5. Explizite Verwendung des Iterators

Iteratoren können auch explizit verwendet werden, allerdings wird der Code in diesem Fall im Vergleich zur for...of-Schleife deutlich komplexer. Es sieht ungefähr so ​​aus:

Var a = ["a", "b", "c"]; Var-Eintrag; while (!(entry = a.next()).done) ( console.log(entry.value); )

II. Iterieren über Array-ähnliche Objekte

Neben echten Arrays gibt es in JavaScript auch solche arrayartige Objekte . Was sie mit echten Arrays gemeinsam haben, ist, dass sie über eine Längeneigenschaft und Eigenschaften verfügen, die als Zahlen benannt sind und den Elementen des Arrays entsprechen. Beispiele hierfür sind das DOM der NodeList-Sammlung und das Argument-Pseudo-Array, das in jeder Funktion/Methode verfügbar ist.

1. Verwenden von Methoden zum Durchlaufen realer Arrays

Zumindest können die meisten, wenn nicht alle Methoden zur Iteration über reale Arrays verwendet werden, um über arrayähnliche Objekte zu iterieren.

Die Konstrukte for und for...in können auf arrayähnliche Objekte genauso angewendet werden wie auf echte Arrays.

forEach und andere Array.prototype-Methoden gelten auch für Array-ähnliche Objekte. Dazu müssen Sie Function.call oder Function.apply verwenden.

Wenn Sie beispielsweise forEach auf die childNodes-Eigenschaft eines Node-Objekts anwenden möchten, gehen Sie folgendermaßen vor:

Array.prototype.forEach.call(node.childNodes, function(child) ( // etwas mit dem untergeordneten Objekt machen));

Um die Wiederverwendung dieses Tricks zu vereinfachen, können Sie einen Verweis auf die Methode Array.prototype.forEach in einer separaten Variablen deklarieren und diese als Verknüpfung verwenden:

// (Angenommen, der gesamte Code unten befindet sich im selben Bereich) var forEach = Array.prototype.forEach; // ... forEach.call(node.childNodes, function(child) ( // etwas mit dem untergeordneten Objekt machen));

Wenn ein Array-ähnliches Objekt über einen Iterator verfügt, kann dieser explizit oder implizit verwendet werden, um auf die gleiche Weise wie bei echten Arrays über das Objekt zu iterieren.

2. Konvertieren Sie in ein echtes Array

Es gibt auch eine andere, sehr einfache Möglichkeit, über ein Array-ähnliches Objekt zu iterieren: Konvertieren Sie es in ein echtes Array und verwenden Sie eine der oben beschriebenen Methoden zum Iterieren über reale Arrays. Zur Konvertierung können Sie die generische Methode Array.prototype.slice verwenden, die auf jedes Array-ähnliche Objekt angewendet werden kann. Das geht ganz einfach, wie im folgenden Beispiel gezeigt:

Var trueArray = Array.prototype.slice.call(arrayLikeObject, 0);

Wenn Sie beispielsweise eine NodeList-Sammlung in ein tatsächliches Array konvertieren möchten, benötigen Sie Code in etwa wie diesen:

Var divs = Array.prototype.slice.call(document.querySelectorAll("div"), 0);

3. Ein Hinweis zu Laufzeitobjekten

Wenn Sie Array.prototype-Methoden auf Laufzeitobjekte (z. B. DOM-Sammlungen) anwenden, sollten Sie sich darüber im Klaren sein, dass nicht garantiert werden kann, dass diese Methoden in allen Laufzeitumgebungen (einschließlich Browsern) ordnungsgemäß funktionieren. Dies hängt vom Verhalten eines bestimmten Objekts in einer bestimmten Ausführungsumgebung ab, oder genauer gesagt, davon, wie die abstrakte Operation HasProperty in diesem Objekt implementiert wird. Das Problem besteht darin, dass der ES5-Standard selbst die Möglichkeit zulässt, dass sich ein Objekt in Bezug auf diesen Vorgang falsch verhält (siehe §8.6.2).

Daher ist es wichtig, die Funktionsweise der Array.prototype-Methoden in jeder Laufzeitumgebung (Browser) zu testen, in der Sie Ihre Anwendung verwenden möchten.