Lors de la création d'une fonction JavaScript avec plusieurs arguments, je suis toujours confronté à ce choix: passer une liste d'arguments vs passer un objet d'options.
Par exemple, j'écris une fonction pour mapper une nodeList à un tableau:
function map(nodeList, callback, thisObject, fromIndex, toIndex){
...
}
Je pourrais plutôt utiliser ceci:
function map(options){
...
}
où options est un objet:
options={
nodeList:...,
callback:...,
thisObject:...,
fromIndex:...,
toIndex:...
}
Quelle est la méthode recommandée? Existe-t-il des directives pour savoir quand utiliser l'un ou l'autre?
[Mise à jour] Il semble y avoir un consensus en faveur de l'objet options, donc j'aimerais ajouter un commentaire: une des raisons pour lesquelles j'ai été tenté d'utiliser la liste d'arguments dans mon cas était d'avoir un comportement cohérent avec le JavaScript intégrée à la méthode array.map.
Array.prototype.map
a une API simple qui ne devrait laisser perplexe aucun codeur semi-expérimenté.Réponses:
Comme beaucoup d'autres, je préfère souvent passer un
options object
à une fonction au lieu de passer une longue liste de paramètres, mais cela dépend vraiment du contexte exact.J'utilise la lisibilité du code comme test décisif.
Par exemple, si j'ai cet appel de fonction:
Je pense que le code est tout à fait lisible tel qu'il est et que passer des paramètres individuels est très bien.
D'autre part, il existe des fonctions avec des appels comme celui-ci:
Complètement illisible à moins que vous ne fassiez des recherches. En revanche, ce code se lit bien:
C'est plus un art qu'une science, mais si je devais nommer des règles empiriques:
Utilisez un paramètre d'options si:
la source
Les arguments multiples concernent principalement les paramètres obligatoires. Il n'y a rien de mal avec eux.
Si vous avez des paramètres optionnels, cela devient compliqué. Si l'un d'eux s'appuie sur les autres, pour qu'ils aient un certain ordre (par exemple, le quatrième a besoin du troisième), vous devez toujours utiliser plusieurs arguments. Presque toutes les méthodes natives EcmaScript et DOM fonctionnent comme ceci. Un bon exemple est la
open
méthode des requêtes XMLHTTP , où les 3 derniers arguments sont facultatifs - la règle est comme "pas de mot de passe sans utilisateur" (voir aussi la documentation MDN ).Les objets Option sont utiles dans deux cas:
undefined
s).Dans votre cas, je recommande
map(nodeList, callback, options)
.nodelist
etcallback
sont obligatoires, les trois autres arguments ne viennent qu'occasionnellement et ont des défauts raisonnables.Un autre exemple est
JSON.stringify
. Vous voudrez peut-être utiliser lespace
paramètre sans passer unereplacer
fonction - alors vous devez appeler…, null, 4)
. Un objet arguments aurait pu être meilleur, bien que ce ne soit pas vraiment raisonnable pour seulement 2 paramètres.la source
L'utilisation de l'approche «options en tant qu'objet» sera la meilleure solution. Vous n'avez pas à vous soucier de l'ordre des propriétés et il y a plus de flexibilité dans les données transmises (paramètres optionnels par exemple)
Créer un objet signifie également que les options peuvent être facilement utilisées sur plusieurs fonctions:
la source
Je pense que si vous instanciez quelque chose ou appelez une méthode d'un objet, vous voulez utiliser un objet options. S'il s'agit d'une fonction qui n'opère que sur un ou deux paramètres et renvoie une valeur, une liste d'arguments est préférable.
Dans certains cas, il est bon d'utiliser les deux. Si votre fonction a un ou deux paramètres obligatoires et un tas de paramètres facultatifs, rendez les deux premiers paramètres obligatoires et le troisième un hachage d'options facultatif.
Dans votre exemple, je le ferais
map(nodeList, callback, options)
. Nodelist et callback sont nécessaires, il est assez facile de dire ce qui se passe simplement en lisant un appel, et c'est comme les fonctions de carte existantes. Toutes les autres options peuvent être passées en tant que troisième paramètre facultatif.la source
Votre commentaire sur la question:
Alors pourquoi ne pas faire ça? (Remarque: c'est du Javascript assez brut. Normalement, j'utiliserais un
default
hachage et le mettrais à jour avec les options transmises en utilisant Object.extend ou JQuery.extend ou similaire ..)Donc, maintenant qu'il est maintenant beaucoup plus évident de savoir ce qui est facultatif et ce qui ne l'est pas, tous ces éléments sont des utilisations valides de la fonction:
la source
Je suis peut-être un peu en retard à la fête avec cette réponse, mais je cherchais les opinions d'autres développeurs sur ce sujet même et je suis tombé sur ce fil.
Je ne suis pas du tout d'accord avec la plupart des intervenants et je partage l'approche des «arguments multiples». Mon argument principal étant qu'il décourage d'autres anti-patterns comme "muter et renvoyer l'objet param", ou "passer le même objet param à d'autres fonctions". J'ai travaillé dans des bases de code qui ont largement abusé de cet anti-pattern, et le débogage de code qui fait cela devient rapidement impossible. Je pense que c'est une règle empirique très spécifique à Javascript, car Javascript n'est pas fortement typé et permet de tels objets structurés de manière arbitraire.
Mon opinion personnelle est que les développeurs doivent être explicites lorsqu'ils appellent des fonctions, éviter de transmettre des données redondantes et éviter de modifier par référence. Ce n'est pas que ce modèle empêche l'écriture de code concis et correct. Je pense simplement qu'il est beaucoup plus facile pour votre projet de tomber dans de mauvaises pratiques de développement.
Considérez le terrible code suivant:
Non seulement ce type d'exigence nécessite une documentation plus explicite pour spécifier l'intention, mais il laisse également la place à de vagues erreurs. Que faire si un développeur modifie
param1
enbar()
? Combien de temps pensez-vous qu'il faudrait parcourir une base de code de taille suffisante pour attraper cela? Certes, cet exemple est légèrement malhonnête car il suppose que les développeurs ont déjà commis plusieurs anti-modèles à ce stade. Mais cela montre comment le passage d'objets contenant des paramètres permet une plus grande marge d'erreur et d'ambiguïté, nécessitant un plus grand degré de conscience et le respect de l'exactitude des constats.Juste mes deux cents sur la question!
la source
Ça dépend.
Sur la base de mon observation sur la conception de ces bibliothèques populaires, voici les scénarios que nous devrions utiliser objet option:
Et les scénarios pour utiliser la liste des paramètres:
la source
L'objet est préférable, car si vous passez un objet, il est facile d'étendre le nombre de propriétés dans ces objets et vous n'avez pas à surveiller l'ordre dans lequel vos arguments ont été passés.
la source
Pour une fonction qui utilise généralement des arguments prédéfinis, vous feriez mieux d'utiliser l'objet option. L'exemple opposé sera quelque chose comme une fonction qui obtient un nombre infini d'arguments comme: setCSS ({height: 100}, {width: 200}, {background: "# 000"}).
la source
Je regarderais de grands projets javascript.
Des choses comme google map, vous verrez fréquemment que les objets instanciés nécessitent un objet mais que les fonctions nécessitent des paramètres. Je pense que cela a à voir avec les arguments OPTION.
Si vous avez besoin d'arguments par défaut ou d'arguments optionnels, un objet serait probablement meilleur car il est plus flexible. Mais si vous ne le faites pas, les arguments fonctionnels normaux sont plus explicites.
Javascript a aussi un
arguments
objet. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/argumentsla source