Quelle est la différence entre forEachet eachdans D3js?
Réponses:
Premièrement, .forEach()ne fait pas partie de d3, c'est une fonction native des tableaux javascript. Donc,
["a", "b", "c"].forEach(function(d, i) { console.log(d + " " + i); });
// Outputs:
a 0
b 1
c 2
Et cela fonctionne même si d3 n'est pas chargé sur la page.
Ensuite, d3 .each()fonctionne sur les sélections d3 (ce que vous obtenez lorsque vous d3.selectAll(...)). Techniquement, vous pouvez faire appel .forEach()à une sélection d3, car dans les coulisses, une sélection d3 est un tableau avec des fonctions supplémentaires (l'une d'entre elles est .each()). Mais vous ne devriez pas faire cela parce que:
Cela ne produira pas le comportement souhaité. Savoir comment utiliser .forEach()avec une sélection d3 afin de produire n'importe quel comportement souhaité nécessiterait une compréhension intime du fonctionnement interne de d3. Alors pourquoi le faire, si vous pouvez simplement utiliser la partie publique documentée de l'API.
Lorsque vous appelez .each(function(d, i) { })une sélection d3, vous obtenez plus que simplement det i: la fonction est invoquée de telle sorte que le thismot - clé n'importe où à l'intérieur de cette fonction pointe vers l'élément HTML DOM associé à d. En d'autres termes, console.log(this)de l'intérieur function(d,i) {}enregistrera quelque chose comme <div class="foo"></div>ou quel que soit l'élément html. Et c'est utile, car vous pouvez alors appeler une fonction sur cet thisobjet afin de modifier ses propriétés CSS, son contenu ou autre. Habituellement, vous utilisez d3 pour définir ces propriétés, comme dans d3.select(this).style('color', '#c33');.
Le principal plats à emporter est que, en utilisant , .each()vous aurez accès à 3 choses dont vous avez besoin: d, thiset i. Avec .forEach(), sur un tableau (comme dans l'exemple du début), vous n'obtenez que 2 choses ( det i), et vous devrez faire beaucoup de travail pour associer également un élément HTML à ces 2 choses. Et c'est, entre autres, comment d3 est utile.
thisest une préoccupation dans de nombreux scénarios d3 où vous passez à des fonctions d'ordre supérieur, y compris par exemple selection.style("color", function(d,i) { /* here 'this' is a DOM element */ }). Je pense que c'est en partie la raison pour laquelle les classes d3 (comme d3.svg.axispar exemple) n'utilisent pas les prototypeméthodes de définition des classes - comme moyen d'éviter de s'appuyer sur this. Mais je ne vois pas comment selection[0].forEach(...)éviter ce problème. N'est-ce pas le même problème?
.forEachaccepté un deuxième paramètre pour la portée this. Cela m'a fait réaliser que vous pouviez utiliser quelque chose de similaire pour obtenir le même effet avec les d3 .each()en utilisant la .bind()méthode de javascript . Par exemple, la portée de la volonté suivante thisà windowet console.log il: selection.each(function() { console.log(this); }.bind(window)).