web-dev-qa-db-ja.com

デフォルトの関数パラメーターの順序

this を読んで、関数の引数のデフォルト値について少し説明しました。

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

それは素晴らしいですが、それから私はこれを試しました:

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

alert fill(liquid="juice")

"Filling the juice with coffee..."で予期しないアラートを受け取りました。それで私はこれを試しました:

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

alert fill(null, "juice")

そしてそれは働いた。それはきれいではありませんが。より良い方法はありますか、またはこれはこれを行う慣用的な方法ですか?

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

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

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

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

alert fill("1L", liquid: "juice", container: "glass")
alert fill()
alert fill "1L"
alert fill "1L", liquid: "water"
83
Jeremy Banks

アミールとジェレミーはすでにこれを持っています。彼らが指摘するように、関数の引数リストのcontainer="mug"は、関数本体のcontainer ?= "mug"の省略形です。

関数を呼び出すときにそれを追加します。

fill(liquid="juice")

javaScriptと同じことを意味します。最初に、liquid変数に値"juice"を割り当てます。次に、liquidfillに渡します。ここでは、CoffeeScriptは特別なことは何も行わず、liquidのスコープは、関数呼び出し以外の場合と同じです。

ちなみに、デフォルトの引数の構文は、引数をスキップできるようにすることでより強力にすることを提案しました(たとえば、(first, middle ?= null, last) ->firstlastに値を割り当てます2つの引数が渡された)、?=ではなく=構文を使用する必要があることを示しています。その提案に対するサポートをここで表明したいかもしれません: issue 1091

8
Trevor Burnham

現在、名前付き引数で呼び出す方法はありません。呼び出し側の引数(名前、位置、デフォルト値、またはその両方)を知る必要があります。これは、javascript/coffeescriptで常に実行できるとは限りません。

代わりに、多くの引数があり、それらに名前を付けてデフォルト値を設定したい場合は、次のようにすることができます。

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()
4
Amir