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, Schreibzugriff auf die Elemente des Arrays durch die Iterationsfunktion zu haben?
Dem Callback werden das Element, der Index und das Array selbst übergeben.
arr.forEach(function(part, index, theArray) {
theArray[index] = "hello world";
});
edit - Wie in einem Kommentar angegeben, kann die Funktion .forEach()
ein zweites Argument enthalten, das als Wert von this
in jedem Aufruf des Rückrufs verwendet wird:
arr.forEach(function(part, index) {
this[index] = "hello world";
}, arr); // use arr as this
Dieses zweite Beispiel zeigt, dass arr
selbst im Callback als this
eingerichtet ist. Man könnte denken, dass das Array, das am Aufruf von .forEach()
beteiligt ist, der default - Wert von this
sein könnte, aber aus irgendeinem Grund ist dies nicht der Fall. this
ist undefined
, wenn das zweite Argument nicht angegeben wird.
Denken Sie auch daran, dass der Array-Prototyp eine ganze Reihe ähnlicher Dienstprogramme enthält und viele Fragen zu Stackoverflow über die eine oder andere Funktion auftauchen, sodass die beste Lösung einfach ein anderes Werkzeug ist. Du hast:
forEach
, um etwas mit oder zu jedem Eintrag in einem Array zu tun;filter
zum Erzeugen eines neuen Arrays, das nur qualifizierte Einträge enthält;map
für die Erstellung eines neuen 1: 1-Arrays durch Transformation eines vorhandenen Arrays;some
, um zu prüfen, ob mindestens ein Element in einem Array zu einer Beschreibung passt.every
, um zu prüfen, ob all -Einträge in einem Array mit einer Beschreibung übereinstimmen;find
, um nach einem Wert in einem Array zu suchenund so weiter. MDN-Link
Lassen Sie uns try, um es einfach zu halten, und diskutieren, wie es tatsächlich funktioniert. Es hat mit Variablentypen und Funktionsparametern zu tun.
Hier ist dein Code, über den wir sprechen:
var arr = ["one","two","three"];
arr.forEach(function(part) {
part = "four";
return "four";
})
alert(arr);
Zunächst einmal sollten Sie hier etwas über Array.prototype.forEach () lesen:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
Zweitens wollen wir kurz über Werttypen in JavaScript sprechen.
Primitives (undefined, null, String, Boolean, Number) speichern einen tatsächlichen Wert.
zB: var x = 5;
Referenztypen (benutzerdefinierte Objekte) speichern den Speicherort des Objekts.
zB: var xObj = { x : 5 };
Und drittens, wie Funktionsparameter funktionieren.
In Funktionen werden Parameter always per Wert übergeben.
Da arr
ein Array von Strings ist, handelt es sich um ein Array von primitive - Objekten. Dies bedeutet, dass sie nach Wert gespeichert werden.
Für Ihren Code oben bedeutet dies, dass jedes Mal, wenn forEach () iteriert, part
dem gleichen Wert wie arr[index]
, entspricht, jedoch nicht dasselbe Objekt.
part = "four";
ändert die Variable part
, lässt jedoch arr
unverändert.
Der folgende Code ändert die gewünschten Werte:
var arr = ["one","two","three"];
arr.forEach(function(part, index) {
arr[index] = "four";
});
alert(arr);
Wenn Array arr
jetzt ein Array von referenztypen war, funktioniert der folgende Code, da Referenztypen einen Speicherort eines Objekts anstelle des eigentlichen Objekts speichern.
var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];
arr.forEach(function(part, index) {
// part and arr[index] point to the same object
// so changing the object that part points to changes the object that arr[index] points to
part.num = "four";
});
alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);
Das folgende Beispiel veranschaulicht, dass Sie part
so ändern können, dass es auf ein neues Objekt zeigt, während die Objekte in arr
allein gespeichert bleiben:
var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];
arr.forEach(function(part, index) {
// the following will not change the object that arr[index] points to because part now points at a new object
part = 5;
});
alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);
Array: ["1", 2, 3, 4]
Ergebnis: ["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()
Originalarray beibehaltenerreicht durch die Einführung einer neuen Variablen modifiedArr
var arr = ["1", 2, 3, 4];
var modifiedArr = arr.map(function(v) {
return "foo"+ v;
});
console.log( "Original:", arr );
console.log( "Modified:", modifiedArr );
Array.prototype.map()
Ändern Sie das ursprüngliche Arrayerreicht durch Neuzuweisung der Variable arr
var arr = ["1", 2, 3, 4];
arr = arr.map(function(v) {
return "foo"+ v;
});
console.log( arr );
Array.prototype.forEach()
Ändern Sie das ursprüngliche Arrayerreicht durch Anzielen der Schlüssel nach Index arr[i]
var arr = ["1", 2, 3, 4];
arr.forEach(function(v, i) {
arr[i] = "foo" + v;
});
console.log( "Original:", arr );
Javascript ist Wertübergabe und bedeutet im Wesentlichen, dass part
eine Kopie des Werts im Array ist.
Um den Wert zu ändern, greifen Sie in Ihrer Schleife auf das Array selbst zu.
arr[index] = 'new value';
Die .forEach-Funktion kann eine Rückruffunktion haben (jedes Element, elementIndex) Grundsätzlich müssen Sie also Folgendes tun:
arr.forEach(function(element,index){
arr[index] = "four"; //set the value
});
console.log(arr); //the array has been overwritten.
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:
var copy = arr.slice();
ersetzen Sie es durch den Index des Arrays.
array[index] = new_value;
Mit den Array-Objektmethoden können Sie den Array-Inhalt ändern, jedoch im Vergleich zu den grundlegenden for-Schleifen. Diesen Methoden fehlt eine wichtige Funktionalität. Sie können den Index für den Lauf nicht ändern.
Wenn Sie beispielsweise das aktuelle Element entfernen und es an einer anderen Indexposition innerhalb desselben Arrays platzieren, können Sie dies problemlos tun. Wenn Sie das aktuelle Element an eine vorherige Position verschieben, besteht kein Problem in der nächsten Iteration, und Sie erhalten dasselbe Element, als hätten Sie nichts getan.
Betrachten Sie diesen Code, bei dem wir das Element an Indexposition 5 an Indexposition 2 verschieben, sobald der Index bis 5 zählt.
var ar = [0,1,2,3,4,5,6,7,8,9];
ar.forEach((e,i,a) => {
i == 5 && a.splice(2,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 6 - 7 7 - 8 8 - 9 9
Wenn Sie jedoch das aktuelle Element an eine Stelle außerhalb der aktuellen Indexposition verschieben, wird dies etwas unordentlich. Das nächste Element wird dann in die Position der verschobenen Elemente verschoben, und in der nächsten Iteration können wir es nicht sehen oder bewerten.
Betrachten Sie diesen Code, bei dem wir das Element an Indexposition 5 an Indexposition 7 verschieben, sobald der Index bis 5 zählt.
var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && a.splice(7,0,a.splice(i,1)[0])
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 5 5 - 6 7 - 7 5 - 8 8 - 9 9
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 der Index im nächsten Lauf an der gleichen Position bleibt und Sie das Element, das an die Stelle des entfernten Elements verschoben wurde, trotzdem auswerten kann. Dies ist bei Array-Methoden nicht möglich. Sie können den Index nicht ändern. Überprüfen Sie den folgenden Code
var a = [0,1,2,3,4,5,6,7,8,9];
a.forEach((e,i,a) => {
i == 5 && (a.splice(7,0,a.splice(i,1)[0]), i--);
console.log(i,e);
}); // 0 0 - 1 1 - 2 2 - 3 3 - 4 4 - 4 5 - 6 7 - 7 5 - 8 8 - 9 9
Wie Sie sehen, wenn wir i
dekrementieren, wird es nicht von 5, sondern von 6 fortfahren.
Denken Sie also daran.
Hier eine ähnliche Antwort mit einer =>
-Style-Funktion:
var data = [1,2,3,4];
data.forEach( (item, i, self) => self[i] = item + 10 );
gibt das Ergebnis:
[11,12,13,14]
Der Parameter self
ist bei der Pfeilstil-Funktion nicht unbedingt erforderlich
data.forEach( (item,i) => data[i] = item + 10);
funktioniert auch.
Um Elemente vollständig hinzuzufügen oder zu löschen, die den Index ändern würden, durch Erweiterung von zhujy_8833, wobei slice () vorgeschlagen wird, eine Kopie zu durchlaufen, zählen Sie einfach die Anzahl der Elemente, die Sie bereits gelöscht oder hinzugefügt haben, und ändern Sie den Index entsprechend. So löschen Sie beispielsweise Elemente:
let values = ["A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"];
let count = 0;
values.slice().forEach((value, index) => {
if (value === "A2" || value === "A5") {
values.splice(index - count++, 1);
};
});
console.log(values);
// Expected: [ 'A0', 'A1', 'A3', 'A4', 'A6', 'A7', 'A8' ]
Elemente einfügen vor:
if (value === "A0" || value === "A6" || value === "A8") {
values.splice(index - count--, 0, 'newVal');
};
// Expected: ['newVal', A0, 'A1', 'A2', 'A3', 'A4', 'A5', 'newVal', 'A6', 'A7', 'newVal', 'A8' ]
Elemente einfügen nach:
if (value === "A0" || value === "A6" || value === "A8") {
values.splice(index - --count, 0, 'newVal');
};
// Expected: ['A0', 'newVal', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'newVal', 'A7', 'A8', 'newVal']
So ersetzen Sie ein Element:
if (value === "A3" || value === "A4" || value === "A7") {
values.splice(index, 1, 'newVal');
};
// Expected: [ 'A0', 'A1', 'A2', 'newVal', 'newVal', 'A5', 'A6', 'newVal', 'A8' ]
Hinweis: Wenn Sie sowohl 'Vorher' als auch 'Nach' Einfügungen implementieren, sollte der Code 'Vor' Einfügungen zuerst behandeln. Andernfalls wäre der umgekehrte Weg nicht wie erwartet