【问题标题】:Default function parameter ordering默认函数参数排序
【发布时间】:2011-07-11 10:30:38
【问题描述】:

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

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

【问题讨论】:

  • 长得丑或吃起来很有趣,很难打

标签: coffeescript


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    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"
    

    【讨论】:

    • 这绝对是规范的做法。 CoffeeScript 无法直接向 JavaScript 添加命名参数,但它的模式匹配对象语法是次优的。遗憾的是,此时模式匹配无法与默认值结合使用,因此 Jeremy 的建议尽可能简洁。
    • 只是想说我找到这个答案有多大帮助,谢谢。 +1
    • 如果您希望能够在没有任何参数的情况下调用该函数,则应该是fill = ({container, liquid} = {}) -> ...fill()。此外,您可以为位置参数使用普通默认值:fill = (quantity="500 ml", {container, liquid} = {}) -> ... 可以称为 fill()fill "1L" 或命名参数的任意组合,例如fill "1L", liquid: "juice".
    • @JulianD。的评论应该添加到答案中!会为我节省很多时间。
    【解决方案3】:

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

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

    fill(liquid="juice")
    

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

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

    【讨论】:

    • 我认为optional function arguments 在 jQuery 等框架中运行良好,但它们会降低可读性。如果在某段代码中有大量使用这种风格的函数,我可能需要查看每个函数定义以了解参数是什么。例如:animate 100, ->animate {delay:100}, ->。这样你也可以animate ->
    • 谢谢,我没有意识到这只是作业。可能是 Python 太多了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多