默认功能参数排序

nmi*_*els 50 coffeescript

通过这个阅读,我找到了函数参数的默认值:

fill = (container, liquid = "coffee") ->
  "Filling the #{container} with #{liquid}..."
Run Code Online (Sandbox Code Playgroud)

这很整洁,但后来我尝试了这个:

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

alert fill(liquid="juice")
Run Code Online (Sandbox Code Playgroud)

并得到了意想不到的警报"Filling the juice with coffee...".那么我试过这个:

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

alert fill(null, "juice")
Run Code Online (Sandbox Code Playgroud)

它起作用了.虽然它不漂亮.有更好的方法,还是这是惯用的方式呢?

小智 83

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

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

alert fill(liquid: "juice", container: "glass")
alert fill()
Run Code Online (Sandbox Code Playgroud)
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"
Run Code Online (Sandbox Code Playgroud)

  • 它应该是`fill =({container,liquid} = {}) - > ...`如果你想能够在没有任何参数的情况下调用函数,`fill()`.此外,您可以使用常规默认值作为位置参数:`fill =(quantity ="500 ml",{container,liquid} = {}) - > ...`可以称为`fill()`,`fill' 1L"`或任何命名参数的组合,例如`fill"1L",liquid:"juice"`. (18认同)
  • 这绝对是规范的方式.CoffeeScript无法直接向JavaScript添加命名参数,但其模式匹配对象语法是下一个最好的方法.遗憾的是,模式匹配目前不能与默认值相结合,因此Jeremy的提议尽可能简洁. (4认同)

Tre*_*ham 8

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

让我在调用函数时添加一下,

fill(liquid="juice")
Run Code Online (Sandbox Code Playgroud)

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

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


Ami*_*mir 5

目前,无法使用命名参数进行调用。它需要知道调用站点的参数(名称、位置和/或默认值),这在 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()
Run Code Online (Sandbox Code Playgroud)