Was ist der Unterschied zwischen forEach
und each
in D3js?
quelle
Erstens .forEach()
ist es nicht Teil von d3, sondern eine native Funktion von Javascript-Arrays. So,
["a", "b", "c"].forEach(function(d, i) { console.log(d + " " + i); });
// Outputs:
a 0
b 1
c 2
Und das funktioniert auch, wenn d3 nicht auf der Seite geladen ist.
Als nächstes arbeitet d3 .each()
an d3-Auswahlen (was Sie erhalten, wenn Sie d3.selectAll(...)
). Technisch gesehen können Sie .forEach()
eine d3-Auswahl aufrufen , da eine d3-Auswahl hinter den Kulissen ein Array mit zusätzlichen Funktionen ist (eine davon ist .each()
). Aber das solltest du nicht tun, weil:
Dies führt nicht zum gewünschten Verhalten. .forEach()
Um zu wissen, wie man mit einer d3-Auswahl arbeitet, um ein gewünschtes Verhalten zu erzeugen, müsste man das Innenleben von d3 genau verstehen. Warum also, wenn Sie nur den dokumentierten öffentlichen Teil der API verwenden können?
Wenn Sie .each(function(d, i) { })
eine d3-Auswahl aufrufen , erhalten Sie mehr als nur d
und i
: Die Funktion wird so aufgerufen, dass das this
Schlüsselwort an einer beliebigen Stelle in dieser Funktion auf das zugeordnete HTML-DOM-Element verweist d
. Mit anderen Worten, console.log(this)
von innen function(d,i) {}
wird so etwas <div class="foo"></div>
oder ein beliebiges HTML-Element protokolliert . Und das ist nützlich, denn dann können Sie die Funktion für dieses this
Objekt aufrufen , um seine CSS-Eigenschaften, Inhalte oder was auch immer zu ändern. Normalerweise verwenden Sie d3, um diese Eigenschaften wie in festzulegen d3.select(this).style('color', '#c33');
.
Der Haupt zum Mitnehmen ist , dass, indem .each()
Sie den Zugriff auf 3 Dinge, die Sie brauchen: d
, this
und i
. Mit .forEach()
einem Array (wie im Beispiel von Anfang an) erhalten Sie nur zwei Dinge ( d
und i
), und Sie müssten eine Menge Arbeit erledigen, um diesen beiden Dingen auch ein HTML-Element zuzuordnen. Und so ist unter anderem d3 nützlich.
this
ist in vielen d3-Szenarien ein Problem, in denen Sie Funktionen höherer Ordnung übergeben, einschließlich beispielsweiseselection.style("color", function(d,i) { /* here 'this' is a DOM element */ })
. Ich glaube, das ist teilweise der Grund, warum d3-Klassen (wied3.svg.axis
zum Beispiel) dieprototype
Methoden zum Definieren von Klassen nicht verwenden - um zu vermeiden, dass man sich darauf verlässtthis
. Aber ich sehe nicht, wieselection[0].forEach(...)
dieses Problem vermieden wird. Ist es nicht das gleiche Problem?.forEach
einen zweiten Parameter für das Scoping akzeptiert habethis
. Mir wurde klar, dass Sie etwas Ähnliches verwenden können, um mit d3s den gleichen Effekt zu erzielen,.each()
indem Sie die.bind()
Methode von Javascript verwenden. Zum Beispiel kann der folgende Wille Umfangthis
zuwindow
werden und console.log es:selection.each(function() { console.log(this); }.bind(window))
.