Voici un moyen très pratique de simplifier l’écriture de fonctions nécessitant un grand nombre d’arguments optionnels.
Au lieu de passer de manière classique les arguments de la fonction un à un, il est possible de passer un unique argument de type objet comprenant l’ensemble des arguments nécessaires. L’objet ainsi passé est communément appelé un “JavaScript Object Literal“.

Manière habituelle
Voici une fonction qui permet d’afficher le contenu d’une carte, l’argument “name” est obligatoire tandis que les arguments “type”, “manacost” et “edition” sont facultatifs.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function showCardBefore(name, type, manacost, edition) { document.write("<p><strong>Name:</strong> " + name + "<br />"); if (typeof type === "string") { document.write("<strong>Type:</strong> " + type + "<br />"); } if (typeof manacost === "string") { document.write("<strong>Mana cost:</strong> " + manacost + "<br />"); } if (typeof edition === "object") { document.write("<strong>Edition:</strong> " + edition[0] + " [" + edition[1] + "]" + "<br />"); } } showCardBefore("Arid Mesa"); showCardBefore("Mark Teixeira", "Birds of Paradise", "G"); showCardBefore("Rustic Clachan", "Land", "", ["Morningtide", "01/02/2008"]); |
Nous appelons la fonction de 3 manières différentes, avec un nombre différent d’arguments à chaque fois. Nous observons que plus il y a d’arguments à saisir et plus la fonction est difficile à lire ou à maintenir.
Manière pratique
Voici la même fonction qui prend en paramètre un seul argument qui contient l’ensemble des données d’une carte.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | function showCardAfter(args) { document.write("<p><strong>Name:</strong> " + args.name + "<br />"); if (typeof args.type === "string") { document.write("<strong>Type:</strong> " + args.type + "<br />"); } if (typeof args.manacost === "string") { document.write("<strong>Mana cost:</strong> " + args.manacost + "<br />"); } if (typeof args.edition === "object") { document.write("<strong>Edition:</strong> " + args.edition.name + " [" + args.edition.release + "]" + "<br />"); } } showCardAfter({ name: "Arid Mesa" }); showCardAfter({ name: "Birds of Paradise", type: "Creature", manacost: "G" }); var card = { name: "Humble", type: "Instant", manacost: "1W", edition: { name : "Zendikar", release : "01/11/2009" } }; showCardAfter(card); |
Le nombre de lignes de code est légèrement plus élevé avec cette seconde méthode mais elle présente un avantage certain lorsque le nombre d’arguments est important :
- La fonction est simplifiée avec l’acceptation d’un unique argument en entrée (args)
- La valeur des arguments devient simple à lire et peut facilement être mise à jour ou modifiée
- Le lien entre la valeur et l’argument est plus direct et donc facilement compris
Utilisation
Si vos fonctions n’utilisent que très peu d’arguments, alors cette technique n’est peut-être pas utile car elle pourrait avoir l’effet inverse.
Par contre sur des fonctions dont le nombre d’arguments n’est pas encore figé ou lorsque vous savez qu’il en faudra beaucoup, alors c’est une technique qui à mon sens vaut le coup d’être appliquée.
Simplification de l’écriture de fonctions = gain de vitesse pour le programme je présume ?
Si en disant “gain de vitesse” tu sous-entends gain de vitesse d’exécution alors je ne pense pas pour cet exemple précis, c’est plutôt une bonne pratique d’écriture qui rend la fonction plus compréhensible pour un développeur qui tomberai dessus pour la première fois.
J’ai un vague souvenir d’un truc équivalent en C++, mais j’en suis plus certain.
Certainement, en Java elle existe depuis Java Tiger (Java 5.0) avec les VarArgs :