Beispiel:
var arr = ["one","two","three"];
arr.forEach(function(part){
part = "four";
return "four";
})
alert(arr);
Das Array hat immer noch seine ursprünglichen Werte. Gibt es eine Möglichkeit, über die Iterationsfunktion Schreibzugriff auf die Elemente des Arrays zu erhalten?
x=[2,3,4]; x=x.map(n=>n*2); // [4,6,8]
Antworten:
Dem Rückruf werden das Element, der Index und das Array selbst übergeben.
Bearbeiten - Wie in einem Kommentar angegeben, kann die
.forEach()
Funktion ein zweites Argument annehmen, das als Wert fürthis
jeden Aufruf des Rückrufs verwendet wird:Dieses zweite Beispiel zeigt
arr
sich wiethis
im Rückruf eingerichtet. Man könnte denken, dass das am.forEach()
Aufruf beteiligte Array der Standardwert von istthis
, aber aus welchem Grund auch immer;this
wird sein,undefined
wenn dieses zweite Argument nicht angegeben wird.(Hinweis: Die obigen Informationen
this
gelten nicht, wenn der Rückruf eine=>
Funktion ist, dathis
sie beim Aufrufen solcher Funktionen niemals an irgendetwas gebunden sind.)Es ist auch wichtig, sich daran zu erinnern, dass der Array-Prototyp eine ganze Familie ähnlicher Dienstprogramme enthält und im Stackoverflow viele Fragen zu der einen oder anderen Funktion auftauchen, sodass die beste Lösung darin besteht, einfach ein anderes Tool auszuwählen. Du hast:
forEach
um mit oder mit jedem Eintrag in einem Array etwas zu tun;filter
zum Erzeugen eines neuen Arrays, das nur qualifizierende Einträge enthält;map
zum Erstellen eines neuen Eins-zu-Eins-Arrays durch Transformieren eines vorhandenen Arrays;some
um zu überprüfen, ob mindestens ein Element in einem Array zu einer Beschreibung passt;every
um zu überprüfen, ob alle Einträge in einem Array mit einer Beschreibung übereinstimmen;find
um nach einem Wert in einem Array zu suchenund so weiter. MDN-Link
quelle
part
(oder sogaro
in es6) ist undefiniert? Wie erhalte ich einen iterierten Wert?part
wäre,undefined
wenn ein Element des Arraysundefined
explizit zugewiesen wurde . "Leere" Slots eines Arrays (ein Array-Eintrag, dem noch kein Wert zugewiesen wurde) werden von den.forEach()
meisten anderen Array-Iterationsmethoden übersprungen ..forEach()
auch ein zweites Argument verwendetthisArg
, das Siethis
im Rückruf verwenden können. HINWEIS: Dies ist ein Argument von.forEach
NICHT ein Argument des Rückrufs.this
das als zweites Argument übergebene Argument zu verwenden.forEach()
, müssen Sie die Rückruffunktion mithilfe der Syntax übergebenfunction()
, da die Verwendung der Pfeilfunktion von ES6 den() => {}
Kontext nicht bindet.Lassen Sie uns versuchen , es einfach zu halten und zu diskutieren, wie es tatsächlich funktioniert. Es hat mit Variablentypen und Funktionsparametern zu tun.
Hier ist Ihr Code, über den wir sprechen:
Zunächst sollten Sie hier etwas über Array.prototype.forEach () lesen:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
Lassen Sie uns zweitens kurz über Werttypen in JavaScript sprechen.
Grundelemente (undefiniert, null, Zeichenfolge, Boolescher Wert, Zahl) speichern einen tatsächlichen Wert.
Ex:
var x = 5;
Referenztypen (benutzerdefinierte Objekte) speichern den Speicherort des Objekts.
Ex:
var xObj = { x : 5 };
Und drittens, wie Funktionsparameter funktionieren.
In Funktionen werden Parameter immer als Wert übergeben.
Da
arr
es sich um ein Array von Strings handelt, handelt es sich um ein Array primitiver Objekte, dh sie werden nach Wert gespeichert.Für Ihren obigen Code bedeutet dies, dass jedes Mal, wenn forEach () iteriert,
part
derselbe Wert wiearr[index]
, aber nicht dasselbe Objekt ist .part = "four";
ändert diepart
Variable, lässt sie aber inarr
Ruhe.Der folgende Code ändert die gewünschten Werte:
Wenn das Array
arr
nun ein Array von Referenztypen war , funktioniert der folgende Code, da Referenztypen einen Speicherort eines Objekts anstelle des tatsächlichen Objekts speichern.Das Folgende zeigt, dass Sie ändern können
part
, um auf ein neues Objekt zu zeigen, während Sie die Objekte inarr
Ruhe lassen:quelle
In functions, parameters are always passed by value.
Was ist mit dem zweiten Beispiel?Array:
[1, 2, 3, 4]
Ergebnis:
["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()
Behalten Sie das ursprüngliche ArrayArray.prototype.forEach()
Originalarray überschreibenquelle
let arr1 = ["1", 2, 3, 4]; arr1.map(function(v) { return "foo"+ v; }); console.log( arr );
Array.prototype.map () Ändern Sie niemals das ursprüngliche Array, für jede Mutation.map
kann definitiv sein Array mutieren undforEach
im Allgemeinen nicht.Javascript wird als Wert übergeben und bedeutet im Wesentlichen, dass
part
es sich um eine Kopie handelt des Werts im Array handelt.Um den Wert zu ändern, greifen Sie auf das Array selbst in Ihrer Schleife zu.
arr[index] = 'new value';
quelle
part
ob es kopiert wird - obwohl Sie Recht haben, dass die Variable kein Zeiger, sondern ein Wert istErsetzen Sie es durch den Index des Arrays.
quelle
Hier ist eine ähnliche Antwort unter Verwendung einer
=>
Stilfunktion:gibt das Ergebnis:
Der
self
Parameter ist bei der Pfeilstilfunktion daher nicht unbedingt erforderlichfunktioniert auch.
quelle
Die .forEach-Funktion kann eine Rückruffunktion haben (jedes Element, elementIndex). Grundsätzlich müssen Sie also Folgendes tun:
Wenn Sie das ursprüngliche Array beibehalten möchten, können Sie eine Kopie davon erstellen, bevor Sie den obigen Vorgang ausführen. Um eine Kopie zu erstellen, können Sie Folgendes verwenden:
quelle
map()
anstelle vonforEach()
.map()
iteriert über das Quellarray und gibt ein neues Array zurück, das die [modifizierte] Kopie des Originals enthält: Das Quellarray bleibt unverändert.Mit den Array-Objektmethoden können Sie den Array-Inhalt ändern, aber im Vergleich zu den grundlegenden for-Schleifen fehlt diesen Methoden eine wichtige Funktionalität. Sie können den Index während des Laufs nicht ändern.
Wenn Sie beispielsweise das aktuelle Element entfernen und an einer anderen Indexposition innerhalb desselben Arrays platzieren, können Sie dies problemlos tun. Wenn Sie das aktuelle Element an eine vorherige Position verschieben, gibt es in der nächsten Iteration kein Problem. Sie erhalten das gleiche nächste Element, als hätten Sie nichts getan.
Betrachten Sie diesen Code, in dem wir das Element an Indexposition 5 auf Indexposition 2 verschieben, sobald der Index bis zu 5 zählt.
Wenn wir das aktuelle Element jedoch an einen Ort jenseits der aktuellen Indexposition verschieben, wird es etwas chaotisch. Dann verschiebt sich das nächste Element in die Position der verschobenen Elemente und in der nächsten Iteration können wir es nicht sehen oder bewerten.
Betrachten Sie diesen Code, in dem wir das Element an Indexposition 5 auf Indexposition 7 verschieben, sobald der Index bis zu 5 zählt.
Wir haben also noch nie 6 in der Schleife getroffen. Normalerweise wird in einer for-Schleife erwartet, dass Sie den Indexwert verringern, wenn Sie das Array-Element nach vorne verschieben, sodass Ihr Index im nächsten Durchlauf an derselben Position bleibt und Sie das an der Stelle des entfernten Elements verschobene Element weiterhin auswerten können. Dies ist mit Array-Methoden nicht möglich. Sie können den Index nicht ändern. Überprüfen Sie den folgenden Code
Wie Sie sehen, wird es beim Dekrementieren
i
nicht von 5 auf 6 fortgesetzt, von wo es übrig geblieben ist.Denken Sie also daran.
quelle
Um Elemente hinzuzufügen oder zu löschen, die den Index ändern würden, zählen Sie einfach die Anzahl der Elemente, die Sie bereits gelöscht oder hinzugefügt haben, und ändern Sie den Index entsprechend, um den Vorschlag von zhujy_8833 zu erweitern. Zum Löschen von Elementen:
So fügen Sie Elemente vor:
So fügen Sie Elemente nach:
So ersetzen Sie ein Element:
Hinweis: Wenn Sie sowohl 'vor' als auch 'nach' Einfügungen implementieren, sollte der Code zuerst 'vor' Einfügungen verarbeiten, anders herum wäre dies nicht wie erwartet
quelle
Sie können dies versuchen, wenn Sie überschreiben möchten
quelle