50 votes

Ordre des paramètres de fonction par défaut

En lisant cela , je suis arrivé au bit sur les valeurs par défaut pour les arguments de fonction:

 fill = (container, liquid = "coffee") ->
  "Filling the #{container} with #{liquid}..."
 

C'est chouette, mais j'ai ensuite essayé ceci:

 fill = (container="mug", liquid = "coffee") ->
  "Filling the #{container} with #{liquid}..."

alert fill(liquid="juice")
 

et obtenu l'alerte inattendue avec "Filling the juice with coffee..." . Alors j'ai essayé ceci:

 fill = (container="mug", liquid = "coffee") ->
  "Filling the #{container} with #{liquid}..."

alert fill(null, "juice")
 

et cela a fonctionné. Ce n'est pas joli quand même. Y at-il une meilleure façon, ou est-ce la façon idiomatique de faire cela?

83voto

Jeremy Banks Points 32470

Semblable à la suggestion d'Amir, voici mon choix pour un compromis entre la pureté de la définition et celle de l'appel. J'ai utilisé une correspondance de modèle afin que vous n'ayez pas besoin d'un autre identificateur ( opts ).

 fill = ({container, liquid}) ->
     container ?= "mug"
     liquid ?= "coffee"

     "Filling the #{container} with #{liquid}..."

alert fill liquid: "juice", container: "glass"
 

Cela fonctionne aussi très bien si vous voulez des arguments de position suivis par des arguments de mots clés:

 fill = (quantity, {container, liquid}) ->
     quantity ?= "500 mL"
     container ?= "mug"
     liquid ?= "coffee"

     "Filling the #{container} with #{quantity} of #{liquid}..."

alert fill "1L", liquid: "juice", container: "glass"
# becomes
alert(fill("1L", { liquid: "juice", container: "glass" }))
 

8voto

Trevor Burnham Points 43199

Amir et Jeremy déjà. Comme ils le soulignent, container="mug" en fonction de la liste d'arguments est vraiment juste un raccourci pour container ?= "mug" dans le corps de la fonction.

Permettez-moi simplement ajouter que lors de l'appel de fonctions,

fill(liquid="juice")

signifie la même chose que dans le JavaScript: tout d'Abord, affectez la valeur "juice" de la liquid variable; puis de passer liquid à fill. CoffeeScript ne pas faire quelque chose de spécial ici, et liquid a la même portée dans cette situation, comme il le ferait à l'extérieur de l'appel de la fonction.

Par ailleurs, j'ai suggéré que l'argument par défaut de la syntaxe devrait être rendu plus puissant par les arguments permettant d'être ignorées (par exemple, (first, middle ?= null, last) -> permettrait d'affecter des valeurs à des first et last si seulement deux arguments ont été passés), et que l' ?= de la syntaxe devrait être utilisé plutôt que d' =. Vous pourriez exprimer votre soutien à cette proposition ici: question 1091.

4voto

Amir Points 3237

Actuellement, il n'y a aucun moyen d'appeler avec des arguments nommés. Cela nécessiterait de connaître les arguments (noms, positions et / ou valeurs par défaut) sur le site appelant, ce qui n'est pas toujours faisable dans javascript / coffeescript.

Au lieu de cela, si vous avez plusieurs arguments et que vous voulez les nommer avec des valeurs par défaut, vous pouvez faire quelque chose comme ceci:

 fill = (opts = {}) ->
    opts.container ?= "mug"
    opts.liquid ?= "coffee"
    "Filling the #{opts.container} with #{opts.liquid}..."

alert fill
    liquid:"juice"
    container:"cup"

alert fill
    liquid:"juice"

alert fill()
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X