La seule différence que je vois dans map et foreach est que map
renvoie un tableau et forEach
ne l'est pas. Cependant, je ne comprends même pas la dernière ligne de la forEach
méthode " func.call(scope, this[i], i, this);
". Par exemple, n'est pas « this
» et « scope
» se référant à un même objet et n'est pas this[i]
et se i
référant à la valeur actuelle dans la boucle?
J'ai remarqué dans un autre message que quelqu'un a dit "À utiliser forEach
lorsque vous voulez faire quelque chose sur la base de chaque élément de la liste. Vous pourriez ajouter des éléments à la page, par exemple. Essentiellement, c'est génial lorsque vous voulez des" effets secondaires ". Je ne sais pas ce que l'on entend par effets secondaires.
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);
}
}
Enfin, y a-t-il de réelles utilisations de ces méthodes en javascript (puisque nous ne mettons pas à jour une base de données) autre que de manipuler des nombres comme celui-ci:
alert([1,2,3,4].map(function(x){ return x + 1})); //this is the only example I ever see of map in javascript.
Merci pour toute réponse.
la source
map
etforEach
? Tout ce que j'obtiens de Google, ce sont des spécifications d'utilisation et des didacticiels.Réponses:
La différence essentielle entre
map
etforEach
dans votre exemple est queforEach
fonctionne sur les éléments du tableau d'origine, alors quemap
renvoie explicitement un nouveau tableau en conséquence.Avec
forEach
vous prenez des mesures avec - et éventuellement en changeant - chaque élément du tableau d'origine. LaforEach
méthode exécute la fonction que vous fournissez pour chaque élément, mais ne renvoie rien (undefined
). D'autre part,map
parcourt le tableau, applique une fonction à chaque élément et émet le résultat sous la forme d'un nouveau tableau .L '«effet secondaire» avec
forEach
est que le tableau d'origine est en cours de modification. "Aucun effet secondaire"map
signifie que, dans un usage idiomatique, les éléments originaux du tableau ne sont pas modifiés; le nouveau tableau est un mappage un-à-un de chaque élément du tableau d'origine - la transformation de mappage étant votre fonction fournie.Le fait qu'il n'y ait pas de base de données impliquée ne signifie pas que vous n'aurez pas à opérer sur des structures de données, qui, après tout, est l'une des essences de la programmation dans n'importe quel langage. Quant à votre dernière question, votre tableau peut contenir non seulement des nombres, mais des objets, des chaînes, des fonctions, etc.
la source
.map
peut tout.forEach
faire (y compris la modification d'éléments), il renvoie simplement une nouvelle liste construite à partir de la fonction itérateur..map()
crée un nouveau tableau et ne modifie pas l'original. Vous pouvez en effet modifier le tableau qui est lui-même mappé, mais ce serait à tout le moins non idiomatique, voire absurde..forEach()
, bien que similaire, applique sa fonction à chaque élément, mais retourne toujoursundefined
. Nonobstant tout ce qui précède, l'OP pose également des questions sur ses propres fonctions spécifiques ajoutées au prototype du tableau; il n'y avait pas d'ES5 ici dans le passé.forEach
fasse que vous ne puissiez pas fairemap
. Vous ne pourriez tout simplement pas vous soucier de la valeur de retour demap
et vous auriez unforEach
. La différence est qu'il est super inefficace à utilisermap
pour les tâches où vous ne souhaitez pas créer un nouveau tableau en fonction des résultats. Donc pour ceux-là, vous utilisezforEach
.for
boucle ancienne . Je ne conteste pas qu'il y a une certaine différence dans «l'efficacité», mais je ne pense pas non plus que quiconque prétende que l'un a une magie que l'autre ne peut pas atteindre d'une manière ou d'une autre. Bien qu'il y ait, en fait, une chose quimap
ne peut pas faire: ne pas retourner un tableau. Il y a une valeur à avoir JS hauteur des attentes des autres langues sur le comportement des favoris fonctionnels commemap
,reduce
,filter
, etc. Par exemple, vous pouvez mettre en œuvre enreduceRight
utilisant des blocs de construction similaires, mais pourquoi ne pas simplement utiliserreduceRight
?b.val = b.val**2
à l'intérieur de l'objet retourné . C'est la chose précise que nous disons est en effet possible mais déroutante et non idiomatique. Normalement, vous renvoyez simplement la nouvelle valeur, pas également l'assignez au tableau d'origine:a=[{val:1},{val:2},{val:3},{val:4}]; a.map((b)=>{b.val**2}); JSON.stringify(a);
La principale différence entre les deux méthodes est conceptuelle et stylistique: vous utilisez
forEach
lorsque vous voulez faire quelque chose sur ou avec chaque élément d'un tableau (faire "avec" est ce que le message que vous citez signifiait par "effets secondaires", je pense) , alors que vous utilisezmap
lorsque vous souhaitez copier et transformer chaque élément d'un tableau (sans changer l'original).Parce que les deux
map
etforEach
appeler une fonction sur chaque élément dans un tableau, et cette fonction est définie par l' utilisateur, il n'y a presque rien que vous pouvez faire avec un seul et non pas avec l'autre. Il est possible, bien que laid, de l'utilisermap
pour modifier un tableau sur place et / ou faire quelque chose avec des éléments de tableau:mais beaucoup plus propre et plus évident quant à votre intention d'utiliser
forEach
:Surtout si, comme c'est généralement le cas dans le monde réel,
el
est une variable lisible par l'homme:De la même manière, vous pouvez facilement utiliser
forEach
pour créer un nouveau tableau:mais c'est plus propre à utiliser
map
:Notez également que, car
map
crée un nouveau tableau, il entraîne probablement au moins un certain impact sur les performances / la mémoire lorsque tout ce dont vous avez besoin est une itération, en particulier pour les grands tableaux - voir http://jsperf.com/map-foreachQuant à savoir pourquoi vous souhaitez utiliser ces fonctions, elles sont utiles chaque fois que vous devez effectuer une manipulation de tableau en javascript, ce qui (même si nous ne parlons que de javascript dans un environnement de navigateur) est assez souvent, presque à tout moment vous accédez à un tableau que vous n'écrivez pas à la main dans votre code. Vous avez peut-être affaire à un tableau d'éléments DOM sur la page, à des données extraites d'une requête AJAX ou à des données saisies dans un formulaire par l'utilisateur. Un exemple courant que j'ai rencontré est l'extraction de données à partir d'une API externe, que vous voudrez peut-être utiliser
map
pour transformer les données dans le format souhaité, puis utiliserforEach
pour itérer sur votre nouveau tableau afin de l'afficher à votre utilisateur.la source
.map()
tout le temps pour modifier des éléments en ligne. J'avais l'impression que c'était le principal avantage de l'utilisation de.map
over.forEach
.map
peut modifier des éléments, oui, mais cela créerait un tableau dont vous n'avez pas besoin. Vous devriez également considérer comment le choix de l'un ou de l'autre permet au lecteur de deviner si vous avez ou non des effets secondairesLa réponse votée (de Ken Redler) est trompeuse.
Un effet secondaire en informatique signifie qu'une propriété d'une fonction / méthode modifie un état global [wiki] . Dans un sens étroit, cela peut également inclure la lecture d'un état global, plutôt que d'arguments. Dans la programmation impérative ou OO, les effets secondaires apparaissent la plupart du temps. Et vous vous en servez probablement sans vous en rendre compte.
La différence significative entre
forEach
etmap
est qu'ellemap
alloue de la mémoire et stocke la valeur renvoyée, tout en laforEach
rejetant. Voir les spécifications emca pour plus d'informations.Quant à la raison pour laquelle les gens disent
forEach
est utilisé lorsque vous voulez un effet secondaire, c'est que la valeur de retour deforEach
est toujoursundefined
. Si cela n'a pas d'effet secondaire (ne change pas l'état global), alors la fonction perd juste du temps CPU. Un compilateur optimisant éliminera ce bloc de code et le remplacera par la valeur finale (undefined
).À propos, il convient de noter que JavaScript n'a aucune restriction sur les effets secondaires. Vous pouvez toujours modifier le tableau d'origine à l'intérieur
map
.la source
C'est une belle question avec une réponse inattendue.
Ce qui suit est basé sur la description officielle de
Array.prototype.map()
.Il n'y a rien qui
forEach()
puisse faire qui nemap()
puisse pas. Autrement dit,map()
est un super-ensemble strict deforEach()
.Bien qu'il
map()
soit généralement utilisé pour créer un nouveau tableau, il peut également être utilisé pour changer le tableau actuel. L'exemple suivant illustre ceci:Dans l'exemple ci-dessus, a
a
été commodément réglé de telle sorte quea[i] === i
pouri < a.length
. Même ainsi, il démontre la puissancemap()
, et en particulier sa capacité à changer le tableau sur lequel il est appelé.Note1:
La description officielle implique que
map()
peut même changer la longueur du tableau sur lequel il est appelé! Cependant, je ne vois pas (une bonne) raison de faire cela.Note 2:
Bien que
map()
map soit un super-ensemble deforEach()
,forEach()
doit toujours être utilisé là où l'on désire modifier un tableau donné. Cela rend vos intentions claires.J'espère que cela a aidé.
la source
mapped = a.map(function (x, i, arr) { arr[i] = x * x * x; return x * x; });.
a.forEach(function(x, i, arr) { ...
, ce qui, encore une fois, est une manière conceptuellement plus correcte lorsque vous avez l'intention de faire muter chaque élément d'origine plutôt que de mapper les valeurs d'un tableau à un autreVous pouvez utiliser
map
comme si c'était le casforEach
.Cependant, il fera plus que nécessaire.
scope
peut être un objet arbitraire; ce n'est en aucun cas nécessairementthis
.Quant à savoir s'il existe de réelles utilisations pour
map
etforEach
, ainsi que pour se demander s'il existe de réelles utilisations pourfor
ou pour leswhile
boucles.la source
scope = scope || this
signifie "siscope
est faux (indéfini, nul, faux, etc.), définissez la portée sur à lathis
place et continuez".Bien que toutes les questions précédentes soient correctes, je ferais certainement une distinction différente. L'utilisation de
map
etforEach
peut impliquer une intention.J'aime utiliser
map
lorsque je transforme simplement les données existantes d'une manière ou d'une autre (mais que je veux m'assurer que les données d'origine restent inchangées.J'aime utiliser
forEach
lorsque je modifie la collection en place.Par exemple,
Ma règle de base est de m'assurer que lorsque vous
map
créez toujours un nouvel objet / valeur à retourner pour chaque élément de la liste source et de retourner plutôt que d'effectuer simplement une opération sur chaque élément.À moins que vous n'ayez vraiment besoin de modifier la liste existante, cela n'a pas vraiment de sens de la modifier en place et s'intègre mieux dans les styles de programmation fonctionnels / immuables.
la source
TL; réponse DR -
map renvoie toujours un autre tableau.
forEach non. C'est à vous de décider ce qu'il fait. Renvoyez un tableau si vous voulez ou faites autre chose si vous ne le faites pas.
La flexibilité est souhaitable dans certaines situations. Si ce n'est pas ce à quoi vous avez affaire, utilisez map.
la source
Encore une fois, je me sens comme un nécromancien ajoutant une réponse à une question qui a été posée il y a 5 ans (heureusement il y a une activité plutôt récente, donc je ne suis pas le seul à déranger les morts :).
D'autres ont déjà posté votre question principale concernant la différence entre les fonctions. Mais pour...
... c'est drôle, tu devrais demander. Juste aujourd'hui, j'ai écrit un morceau de code qui attribue un certain nombre de valeurs d'une expression régulière à plusieurs variables en utilisant la carte pour la transformation. Il a été utilisé pour convertir une structure textuelle très compliquée en données visualisables ... mais par souci de simplicité, je vais offrir un exemple utilisant des chaînes de date, car celles-ci sont probablement plus familières pour tout le monde (cependant, si mon problème avait réellement été avec les dates , au lieu de la carte, j'aurais utilisé Date-object, qui aurait fait le travail à merveille tout seul).
Donc ... alors que ce n'était qu'un exemple - et n'a fait qu'une transformation très basique pour les données (juste à titre d'exemple) ... l'avoir fait sans carte aurait été une tâche beaucoup plus fastidieuse.
Certes, il est écrit dans une version de JavaScript que je ne pense pas que trop de navigateurs prennent encore en charge (au moins complètement) mais - nous y arrivons. Si j'avais besoin de l'exécuter dans un navigateur, je pense qu'il se transpilerait bien.
la source