Подтвердить что ты не робот

Настройка параметров функции по умолчанию

Чтение через 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")

и это сработало. Это не очень. Есть ли лучший способ, или это идиоматический способ сделать это?

4b9b3361

Ответ 1

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"

Ответ 2

У Амира и Джереми уже есть это. Как они отмечают, container="mug" в списке аргументов функции действительно является просто сокращением для container ?= "mug" в теле функции.

Позвольте мне добавить, что при вызове функций

fill(liquid="juice")

означает то же, что и в JavaScript: во-первых, присвойте значение "juice" переменной liquid; затем пройдите liquid до fill. CoffeeScript не делает ничего особенного здесь, а liquid имеет ту же область видимости в этой ситуации, что и вне вызова функции.

Кстати, я предположил, что синтаксис аргумента по умолчанию должен быть более мощным, позволяя пропускать аргументы (например, (first, middle ?= null, last) -> будет присваивать значения first и last, если были переданы только два аргумента), и что вместо = следует использовать синтаксис ?=. Вы можете выразить поддержку этому предложению здесь: issue 1091.

Ответ 3

В настоящее время нет способа вызова с именованными аргументами. Это потребует знания аргументов (имен, позиций и/или значений по умолчанию) на вызывающем сайте, что не всегда возможно в 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()