Plusieurs arguments contre objet d'options
Lors de la création d'une fonction JavaScript avec plusieurs arguments, je suis toujours confronté à ce choix: passer d'une liste d'arguments contre passer un objet d'options.
Par exemple je suis en train d'écrire une fonction pour mapper une nodeList à un tableau:
function map(nodeList, callback, thisObject, fromIndex, toIndex){
...
}
Je pourrais utiliser cette:
function map(options){
...
}
où les options est un objet:
options={
nodeList:...,
callback:...,
thisObject:...,
fromIndex:...,
toIndex:...
}
Dont l'une est la méthode recommandée? Existe-il des lignes directrices pour savoir quand utiliser l'un contre l'autre?
[Mise à jour] Il semble y avoir un consensus en faveur de l'objet options, donc je voudrais 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é dans la gamme.méthode map.
- La deuxième option vous donne les arguments nommés, ce qui est une bonne chose à mon avis.
- Sont-ils facultatifs ou obligatoires arguments?
- dans mon exemple, les trois derniers sont en option.
- Parce que vos deux derniers arguments sont très similaires, si l'utilisateur est passé seulement l'un ou l'autre, tu n'avais jamais vraiment être en mesure de savoir qui était prévu. À cause de cela, vous seriez presque besoin d'arguments nommés. Mais je peux comprendre que vous voulez maintenir une API similaire à l'API native.
- La modélisation d'après l'API native n'est pas une mauvaise chose, si votre fonction fait la même chose. Il s'agit de "ce qui rend le code plus readablae."
Array.prototype.map
a une API simple qui ne devrait pas laisser un semi-connu codeur déconcertant plus.
Vous devez vous connecter pour publier un commentaire.
Comme beaucoup d'autres, je préfèrent souvent passer un
options object
à une fonction plutôt que de passer une longue liste de paramètres, mais cela dépend vraiment du contexte exact.- Je utiliser la lisibilité du code comme le révélateur.
Par exemple, si j'ai cette appel de la fonction:
Je pense que le code est tout à fait lisible de la façon dont il est et passage de paramètres individuels est tout simplement parfait.
D'autre part, il y a des fonctions d'appels, comme ceci:
Complètement illisible, sauf si vous faites un peu de recherche. D'autre part, ce code se lit bien:
Il est plus un art qu'une science, mais si je devais le nom de règles de base:
Utiliser un paramètre options si:
InitiateTransferProtocol(protocol: "http", sync: false, ....
?initiateTransferProtocol("http", false, 150, 90, null, true, 18);
Ah, le bon vieux " jours de Win32 et COM:CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_Isesoft, (void **)&pDispatch)
Plusieurs arguments sont pour la plupart des paramètres obligatoires. Il n'y a rien de mal avec eux.
Si vous avez des paramètres facultatifs, cela devient compliqué. Si l'un d'eux s'appuie sur les autres, de sorte qu'ils ont un certain ordre (par exemple, le quatrième besoins à la troisième), vous devez tout de même utiliser plusieurs arguments. Presque tous les indigènes EcmaScript et DOM-méthodes de travail de ce genre. Un bon exemple est le
ouvrir
méthode de XMLHTTPrequests, où les 3 derniers arguments sont facultatifs - la règle est comme "pas de mot de passe sans que l'utilisateur" (voir aussi MDN docs).Option objets utile dans deux cas:
undefined
s).Dans votre cas, je vous recommande
map(nodeList, callback, options)
.nodelist
etcallback
sont nécessaires, les trois autres arguments viennent qu'occasionnellement et qui ont de bonnes valeurs par défaut.Un autre exemple est
JSON.stringify
. Vous pouvez utiliser lespace
paramètre sans passer unreplacer
la fonction, alors vous devez appeler…, null, 4)
. Un objet arguments auraient été mieux, même si ce n'est pas vraiment raisonnable pour seulement 2 paramètres.À l'aide de l'option "options comme un objet' approche va être meilleur. Vous n'avez pas à vous soucier de l'ordre des propriétés et il n'y a plus de flexibilité en ce que les données sont transmises (en option paramètres par exemple)
La création d'un objet signifie également les options pourrait facilement être utilisé sur de multiples fonctions:
Je pense que si vous êtes à l'instanciation d'une chose ou d'appeler une méthode d'un objet, vous souhaitez utiliser un objet d'options. Si c'est une fonction qui fonctionne 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 d'option, de faire les deux premiers paramètres requis, et le troisième en option options de hachage.
Dans votre exemple, je ferais
map(nodeList, callback, options)
. Nodelist et de rappel sont nécessaires, il est assez facile de dire ce qui se passe juste par la lecture d'un appel à elle, et c'est comme carte existante fonctions. Toutes les autres options peuvent être passées en tant que troisième paramètre facultatif.Votre commentaire sur la question:
Alors pourquoi ne pas le faire? (Note: C'est assez cru Javascript. Normalement, je voudrais utiliser un
default
de hachage et de mettre à jour avec les options passées en utilisant Objet.étendre ou JQuery.étendre ou similaire..)Alors, maintenant, car il est maintenant beaucoup plus évident que ce qui est facultatif et n'est-ce pas, tous ces éléments sont valides utilisations de la fonction:
Il dépend.
Fonde sur mon observation sur les bibliothèques populaires de conception, voici les scénarios que nous devrions utiliser l'option objet:
ordre.
assez pour dire les paramètres "dans le sens". Il pourrait donc besoin d'une forte
nom du paramètre pour des raisons de lisibilité.
Et des scénarios pour utiliser le paramètre de la liste:
Objet est plus préférable, parce que si vous passez un objet, il est facile d'étendre le nombre de propriétés des objets et que vous n'avez pas à regarder pour l'ordre dans lequel vos arguments a été adoptée.
J'ai peut-être un peu en retard à la fête avec cette réponse, mais j'étais à la recherche pour d'autres développeurs, les opinions sur ce sujet et suis tombé sur ce thread.
Je suis très en désaccord avec la plupart des intervenants, et à côté avec les multiples arguments' approche. Mon argument principal étant qu'elle décourage d'autres anti-modèles comme "la mutation et le retour de l'param objet", ou "passer la même param objet à d'autres fonctions". J'ai travaillé dans des bases de codes qui ont largement abusé de cet anti-modèle, et le débogage de code qui fait cela devient vite impossible. Je pense que c'est une très Javascript-règle particulière de pouce, car le Javascript n'est pas fortement typé et permet arbitrairement les objets structurés.
Mon opinion personnelle est que les développeurs doivent être explicite lors de l'appel de fonctions, éviter de passer des données redondantes et d'éviter de modifier par référence. Ce n'est pas que ce motif s'oppose à l'écriture concise, le code est correct. Je pense tout simplement que c'est beaucoup plus facile pour votre projet de tomber dans de mauvaises pratiques en matière de développement.
Envisager la suite de terribles code:
Non seulement ce genre d'exiger plus explicite de la documentation pour spécifier l'intention, mais il laisse aussi la place pour un vague des erreurs.
Que faire si un développeur modifie
param1
dansbar()
? Combien de temps pensez-vous qu'il prendrait en regardant à travers une base de code de sufficident taille pour attraper ce?Certes, c'est l'exemple est un peu hypocrite car elle suppose que les développeurs ont déjà commis plusieurs anti-patrons par ce point. Mais elle montre comment le passage des objets contenant des paramètres permet une plus grande place à l'erreur et à l'ambiguïté, nécessitant un plus grand degré de conscience et de respect de const exactitude.
Juste mes deux cents sur la question!
Pour une fonction qui utilise habituellement certains arguments prédéfinis vous permettrait de mieux utiliser l'option de l'objet. L'exemple ci-contre sera quelque chose comme une fonction qui est d'obtenir le nombre infini des arguments comme: setCSS({height:100},{largeur:200},{background:"#000"}).
Je regarde les grands projets javascript.
Des choses comme google map, vous rencontrerez fréquemment que les objets instanciés besoin d'un objet, mais les fonctions requièrent des paramètres. Je pense que cela a à faire avec l'OPTION argumemnts.
Si vous avez besoin d'arguments par défaut ou en option arguments d'un objet serait probablement préférable car il est plus souple. Mais si vous n'avez pas fonctionnel normal arguments sont plus explicites.
Javascript a un
arguments
objet de trop.https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments