51

通读这篇文章,我想到了函数参数的默认值:

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")

它奏效了。虽然不漂亮。有没有更好的方法,或者这是惯用的方法?

4

3 回答 3

84
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"
于 2011-03-09T02:22:46.380 回答
8

阿米尔和杰里米已经有了这个。正如他们所指出的,container="mug"函数的参数列表实际上只是container ?= "mug"函数体中的简写。

让我在调用函数时补充一点,

fill(liquid="juice")

与 JavaScript 中的含义相同:首先,将值分配给"juice"变量liquid;然后传递liquidfill. CoffeeScript 在这里没有做任何特别的事情,并且liquid在这种情况下具有与函数调用之外相同的范围。

顺便说一句,我建议应该通过允许跳过参数来使默认参数语法更强大(例如,如果只传递两个参数,(first, middle ?= null, last) ->则将赋值给它),并且应该使用语法而不是. 您可能想在此处表达对该提议的支持:issue 1091firstlast?==

于 2011-03-09T04:27:51.353 回答
4

目前,无法使用命名参数进行调用。它需要知道调用站点的参数(名称、位置和/或默认值),这在 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()
于 2011-03-09T02:06:33.523 回答