Welchen Nutzen hat die JavaScript forEach-Methode (diese Karte kann das nicht)?

Lesezeit: 12 Minuten

Benutzer-Avatar
JohnMerlino

Der einzige Unterschied, den ich in map und foreach sehe, ist dieser map gibt ein Array zurück und forEach ist nicht. Allerdings verstehe ich nicht einmal die letzte Zeile der forEach Methode “func.call(scope, this[i], i, this);“. Zum Beispiel ist nicht “this” und “scope” bezieht sich auf dasselbe Objekt und ist es nicht this[i] und i bezieht sich auf den aktuellen Wert in der Schleife?

Ich habe in einem anderen Beitrag bemerkt, dass jemand sagte: “Use forEach wenn Sie etwas auf der Grundlage jedes Elements der Liste tun möchten. Sie könnten beispielsweise Dinge zur Seite hinzufügen. Im Wesentlichen ist es großartig, wenn Sie “Nebenwirkungen” wollen. Ich weiß nicht, was mit Nebenwirkungen gemeint ist.

Array.prototype.map = function(fnc) {
    var a = new Array(this.length);
    for (var i = 0; i < this.length; i++) {
        a[i] = fnc(this[i]);
    }
    return a;
}

Array.prototype.forEach = function(func, scope) {
    scope = scope || this;
    for (var i = 0, l = this.length; i < l; i++) {
        func.call(scope, this[i], i, this);
    }
}

Gibt es schließlich noch andere Verwendungsmöglichkeiten für diese Methoden in JavaScript (da wir keine Datenbank aktualisieren), als Zahlen wie die folgenden zu manipulieren?

alert([1,2,3,4].map(function(x){ return x + 1})); // This is the only example I ever see of map in JavaScript.

  • Wie kann man die Definition einer Funktion von nativem JavaScript finden, wie Sie es mit getan haben? map und forEach? Alles, was ich von Google bekomme, sind Nutzungsspezifikationen und Tutorials.

    – Woodrow Shigeru

    10. Oktober 2017 um 10:47 Uhr

  • Siehe auch sprachunabhängig. Gibt es einen Unterschied zwischen foreach und map?

    – Bergi

    19. August 2020 um 20:51 Uhr

Benutzer-Avatar
Ken Redler

Der wesentliche Unterschied zw map und forEach in deinem Beispiel ist das forEach arbeitet mit den ursprünglichen Array-Elementen, wohingegen map gibt als Ergebnis explizit ein neues Array zurück.

Mit forEach Sie unternehmen eine Aktion mit jedem Element im ursprünglichen Array und ändern es optional. Das forEach -Methode führt die Funktion aus, die Sie für jedes Element bereitstellen, gibt aber nichts zurück (undefined). Auf der anderen Seite, map geht durch das Array, wendet eine Funktion auf jedes Element an und gibt das Ergebnis als neues Array aus.

Die “Nebenwirkung” mit forEach ist, dass das ursprüngliche Array geändert wird. „Keine Nebenwirkung“ mit map bedeutet, dass im idiomatischen Sprachgebrauch die ursprünglichen Array-Elemente sind nicht geändert; Das neue Array ist eine Eins-zu-Eins-Zuordnung jedes Elements im ursprünglichen Array – die Zuordnungstransformation ist Ihre bereitgestellte Funktion.

Die Tatsache, dass keine Datenbank beteiligt ist, bedeutet nicht, dass Sie nicht mit Datenstrukturen operieren müssen, was schließlich eine der Essenzen der Programmierung in jeder Sprache ist. Was Ihre letzte Frage betrifft, kann Ihr Array nicht nur Zahlen, sondern auch Objekte, Zeichenfolgen, Funktionen usw. enthalten.

  • Anmerkung aus der Zukunft: Diese Antwort ist eigentlich Unsinn; .map kann alles .forEach tun kann (einschließlich des Änderns von Elementen), gibt es einfach eine neue Liste zurück, die aus der Iteratorfunktion erstellt wurde.

    – Travis Webb

    12. Mai 2015 um 5:06 Uhr

  • Antwort aus der Vergangenheit: Ich widerspreche respektvoll. .map() erstellt ein neues Array und ändert das Original nicht. Sie könnten das Array, das selbst abgebildet wird, tatsächlich ändern, aber das wäre zumindest nicht idiomatisch, wenn nicht sogar unsinnig. .forEach()obwohl ähnlich, wendet seine Funktion auf jedes Element an, kehrt aber immer zurück undefined. Ungeachtet all dessen fragt das OP auch nach seinen eigenen spezifischen Funktionen, die dem Array-Prototyp hinzugefügt wurden. Früher gab es hier keinen ES5.

    – Ken Redler

    13. Mai 2015 um 15:45 Uhr

  • Da ist noch nichts forEach tut, was Sie nicht tun können map. Sie könnten sich einfach nicht um den Rückgabewert kümmern map und du hättest ein forEach. Der Unterschied ist, dass es super ineffektiv ist map für Aufgaben, bei denen Sie kein neues Array basierend auf Ergebnissen erstellen möchten. Also für diejenigen, die Sie verwenden forEach.

    – stupsen

    23. Dezember 2015 um 0:07 Uhr

  • @poke: ..und ebenso könnten Sie mit einem einfachen alten alles tun, was Sie brauchen for Schleife. Ich bin nicht anderer Meinung, dass es einen gewissen Unterschied in der “Effektivität” gibt, aber ich glaube auch nicht, dass irgendjemand argumentiert, dass der eine etwas Magie hat, das der andere nicht irgendwie erreichen kann. Obwohl es in der Tat eine Sache gibt map kann nicht: kein Array zurückgeben. Es ist wertvoll, wenn JS die Erwartungen anderer Sprachen in Bezug auf das Verhalten von funktionalen Favoriten wie erfüllt map, reduce, filteretc. ZB könnten Sie implementieren reduceRight mit ähnlichen Bausteinen, aber warum nicht einfach verwenden reduceRight?

    – Ken Redler

    23. Dezember 2015 um 16:47 Uhr


  • @ChinotoVokro, dein Beispiel ist explizit mutiert das ursprüngliche Array durch Zuweisung b.val = b.val**2 innerhalb des zurückgegebenen Objekts. Das ist genau das, was wir sagen, ist zwar möglich, aber verwirrend und nicht idiomatisch. Normalerweise geben Sie einfach den neuen Wert zurück und weisen ihn nicht auch dem ursprünglichen Array zu: a=[{val:1},{val:2},{val:3},{val:4}]; a.map((b)=>{b.val**2}); JSON.stringify(a);

    – Ken Redler

    19. Oktober 2017 um 17:39 Uhr

Benutzer-Avatar
nabinowitz

Der Hauptunterschied zwischen den beiden Methoden ist konzeptionell und stilistisch: Sie verwenden forEach wenn Sie etwas tun möchten zu oder mit jedes Element eines Arrays (doing “with” ist das, was der Beitrag, den Sie zitieren, mit “Nebenwirkungen” gemeint hat, denke ich), während Sie verwenden map wenn du willst kopieren und transformieren jedes Element eines Arrays (ohne das Original zu verändern).

Denn beides map und forEach Rufen Sie eine Funktion für jedes Element in einem Array auf, und diese Funktion ist benutzerdefiniert, es gibt fast nichts, was Sie mit dem einen und nicht mit dem anderen tun können. Es ist möglich, obwohl hässlich, zu verwenden map um ein Array direkt zu ändern und/oder etwas mit Array-Elementen zu tun:

var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.map(function(el) {
    el.val++; // modify element in-place
    alert(el.val); // do something with each element
});
// a now contains [{ val: 2 }, { val: 3 }, { val: 4 }]

aber viel sauberer und offensichtlicher in Bezug auf Ihre Verwendungsabsicht forEach:

var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.forEach(function(el) {
    el.val++;
    alert(el.val);
});

Vor allem, wenn, wie in der Realität üblich, el ist eine nützliche menschenlesbare Variable:

cats.forEach(function(cat) {
    cat.meow(); // nicer than cats[x].meow()
});

Auf die gleiche Weise können Sie problemlos verwenden forEach um ein neues Array zu erstellen:

var a = [1,2,3],
    b = [];
a.forEach(function(el) {
    b.push(el+1);
});
// b is now [2,3,4], a is unchanged

aber es ist sauberer zu verwenden map:

var a = [1,2,3],
    b = a.map(function(el) {
        return el+1;
    });

Beachten Sie auch das, weil map ein neues Array erstellt, wird es wahrscheinlich zumindest einige Leistungs- / Speichereinbußen geben, wenn Sie nur Iterationen benötigen, insbesondere bei großen Arrays – siehe http://jsperf.com/map-foreach

Warum Sie diese Funktionen verwenden sollten, sie sind jedes Mal hilfreich, wenn Sie Array-Manipulationen in JavaScript durchführen müssen, was (auch wenn wir nur über JavaScript in einer Browserumgebung sprechen) ziemlich oft, fast immer der Fall ist Sie greifen auf ein Array zu, das Sie nicht von Hand in Ihren Code schreiben. Möglicherweise haben Sie es mit einer Reihe von zu tun Dom Elemente auf der Seite oder Daten aus einer Ajax Anfrage oder vom Benutzer in ein Formular eingegebene Daten. Ein häufiges Beispiel, auf das ich stoße, ist das Abrufen von Daten aus einer externen API, die Sie möglicherweise verwenden möchten map um die Daten in das gewünschte Format umzuwandeln und dann zu verwenden forEach um über Ihr neues Array zu iterieren, um es Ihrem Benutzer anzuzeigen.

  • Ich sehe Leute, die verwenden .map() die ganze Zeit, um Inline-Elemente zu ändern. Ich hatte den Eindruck, dass dies der Hauptvorteil der Verwendung war .map Über .forEach

    – Chovy

    7. Oktober 2016 um 6:51 Uhr


  • @chovy Ich glaube, dass Sie entscheiden sollten, ob Sie eine Reihe von Ergebnissen erzielen möchten. .map kann Elemente ändern, ja, aber es würde ein Array erstellen, das Sie nicht benötigen. Sie sollten auch bedenken, dass die Auswahl des einen oder anderen den Leser erraten lässt, ob Sie Nebenwirkungen haben oder nicht

    – leewz

    26. Oktober 2016 um 3:09 Uhr

Benutzer-Avatar
Jack Tang

Die gewählte Antwort (von Ken Redler) ist irreführend.

EIN Nebeneffekt in der Informatik bedeutet, dass eine Eigenschaft einer Funktion/Methode einen globalen Zustand verändert [Wikipedia]. Im engeren Sinne kann dies auch das Lesen von einem globalen Zustand statt von Argumenten beinhalten. Im Imperativ oder OO-Programmierungtreten die meiste Zeit Nebenwirkungen auf. Und Sie nutzen es wahrscheinlich, ohne es zu merken.

Der wesentliche Unterschied zw forEach und map ist das map weist Speicher zu und speichert den Rückgabewert, während forEach wirft es weg. Sehen die ECMA-Spezifikation für mehr Informationen.

Als Grund, warum die Leute sagen forEach wird verwendet, wenn Sie einen Nebeneffekt wünschen, der der Rückgabewert von ist forEach ist immer undefined. Wenn es keine Nebenwirkung hat (den globalen Status nicht ändert), verschwendet die Funktion nur CPU-Zeit. Ein optimierender Compiler eliminiert diesen Codeblock und ersetzt ihn durch den endgültigen Wert (undefined).

Übrigens ist anzumerken, dass JavaScript keine Beschränkung auf Seiteneffekte hat. Sie können das ursprüngliche Array darin immer noch ändern map.

var a = [1,2,3]; //original
var b = a.map( function(x,i){a[i] = 2*x; return x+1} );
console.log("modified=%j\nnew array=%j",a,b);
// output:
// modified=[2,4,6]
// new array=[2,3,4]

  • Es macht immer Spaß, diese Frage und ihre Antworten und Kommentare alle paar Jahre zu wiederholen. Die Art und Weise, wie map im Hinblick auf die Speicherzuweisung in JS implementiert wird, ist ein weiterer netter Aspekt.

    – Ken Redler

    26. Oktober 2019 um 23:46 Uhr

Benutzer-Avatar
Sumukh Barve

Dies ist eine schöne Frage mit einer unerwarteten Antwort.

Das Folgende basiert auf der offizielle Beschreibung von Array.prototype.map().

Es gibt nichts das forEach() kann das tun map() kann nicht. Das ist, map() ist ein strikte Supermenge von forEach().

Obwohl map() wird normalerweise verwendet, um ein neues Array zu erstellen, es kann sein Auch verwendet werden, um das aktuelle Array zu ändern. Das folgende Beispiel verdeutlicht dies:

var a = [0, 1, 2, 3, 4], mapped = null;
mapped = a.map(function (x) { a[x] = x*x*x; return x*x; });
console.log(mapped); // logs [0, 1, 4, 9, 16]  As expected, these are squares.
console.log(a); // logs [0, 1, 8, 27, 64] These are cubes of the original array!!

Im obigen Beispiel a wurde bequem so eingestellt a[i] === i zum i < a.length. Trotzdem demonstriert es die Macht von map()und insbesondere seine Fähigkeit, das Array zu ändern, auf dem es aufgerufen wird.

Anmerkung 1:

Die offizielle Beschreibung impliziert dies map() kann sich sogar ändern Länge das Array, auf dem es aufgerufen wird! Ich sehe jedoch keinen (guten) Grund dafür.

Anmerkung 2:

Während map() map ist eine Obermenge von forEach(), forEach() sollte immer noch verwendet werden, wenn man die Änderung eines bestimmten Arrays wünscht. Dies macht Ihre Absichten klar.

Sie können verwenden map als wäre es forEach.

Es wird jedoch mehr tun, als es muss.

scope kann ein beliebiges Objekt sein; es ist keineswegs unbedingt this.

Ob es wirkliche Verwendungen für gibt map und forEachsowie um zu fragen, ob es wirkliche Verwendungen dafür gibt for oder while Schleifen.

  • Aber warum werden hier sowohl “scope” als auch “this” aufgerufen: func.call(scope, this[i], ich, dies); Ist Geltungsbereich nicht ein Parameter, der gleich dem aktuellen Objekt ist, das “this” ist?

    – JohnMerlino

    14. Juni 2010 um 17:07 Uhr

  • Nein, es kann gleich dem aktuellen Objekt sein. Das Objekt selbst wird als dritter Parameter an das Array übergeben. scope = scope || this bedeutet „wenn scope ist falsch (undefiniert, null, falsch usw.) Bereich festlegen auf this stattdessen und weitermachen”.

    – Wumbleton

    15. Juni 2010 um 1:16 Uhr

  • Können Sie mir ein Beispiel verlinken, wenn es nicht gleich ist?

    – JohnMerlino

    15. Juni 2010 um 12:41 Uhr

  • developer.mozilla.org/en/Core_JavaScript_1.5_Reference/… hat einen unter “Den Inhalt eines Arrays mit einer Objektmethode drucken”

    – Wumbleton

    16. Juni 2010 um 2:49 Uhr

Benutzer-Avatar
Peter Mortensen

Während alle vorherigen Fragen richtig sind, würde ich definitiv eine andere Unterscheidung treffen. Die Verwendung von map und forEach kann Absicht bedeuten.

benutze ich gerne map wenn ich die vorhandenen Daten einfach auf irgendeine Weise transformiere (aber sicherstellen möchte, dass die Originaldaten unverändert bleiben).

benutze ich gerne forEach wenn ich die Sammlung an Ort und Stelle ändere.

Zum Beispiel,

var b = [{ val: 1 }, { val: 2 }, { val: 3 }];
var c = b.map(function(el) {
    return { val: el.val + 1 }; // modify element in-place
});
console.log(b);
//  [{ val: 1 }, { val: 2 }, { val: 3 }]
console.log(c);
//  [{ val: 3 }, { val: 4 }, { val: 5 }]

Meine Faustregel lautet, darauf zu achten, wann Sie map Sie erstellen immer ein neues Objekt/einen neuen Wert, der für jedes Element der Quellliste und zurückgegeben werden soll Rückkehr es, anstatt nur eine Operation für jedes Element auszuführen.

Wenn Sie die vorhandene Liste nicht wirklich ändern müssen, ist es nicht wirklich sinnvoll, sie an Ort und Stelle zu ändern, und passt besser hinein funktionale/unveränderliche Programmierung Stile.

  • Aber warum werden hier sowohl “scope” als auch “this” aufgerufen: func.call(scope, this[i], ich, dies); Ist Geltungsbereich nicht ein Parameter, der gleich dem aktuellen Objekt ist, das “this” ist?

    – JohnMerlino

    14. Juni 2010 um 17:07 Uhr

  • Nein, es kann gleich dem aktuellen Objekt sein. Das Objekt selbst wird als dritter Parameter an das Array übergeben. scope = scope || this bedeutet „wenn scope ist falsch (undefiniert, null, falsch usw.) Bereich festlegen auf this stattdessen und weitermachen“.

    – Wumbleton

    15. Juni 2010 um 1:16 Uhr

  • Können Sie mir ein Beispiel verlinken, wenn es nicht gleich ist?

    – JohnMerlino

    15. Juni 2010 um 12:41 Uhr

  • developer.mozilla.org/en/Core_JavaScript_1.5_Reference/… hat einen unter “Den Inhalt eines Arrays mit einer Objektmethode drucken”

    – Wumbleton

    16. Juni 2010 um 2:49 Uhr

Benutzer-Avatar
Peter Mortensen

TL;DR-Antwort —

Karte gibt immer ein anderes Array zurück.

für jeden nicht. Es liegt an Ihnen, zu entscheiden, was es tut. Geben Sie ein Array zurück, wenn Sie möchten, oder tun Sie etwas anderes, wenn Sie dies nicht möchten.

Flexibilität ist in bestimmten Situationen wünschenswert. Wenn es nicht für das ist, womit Sie es zu tun haben, verwenden Sie es Karte.

1184480cookie-checkWelchen Nutzen hat die JavaScript forEach-Methode (diese Karte kann das nicht)?

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

Privacy policy