Экзистенциальные операторы условного присваивания в Coffeescript

При чтении документации Coffeescript я был смущен скудной документацией по экзистенциальным операторам. В документации указано

Он (?=) также может использоваться для более безопасного условного назначения, чем ||=обеспечивает, в случаях, когда вы можете обрабатывать числа или строки.

В чем разница между оператором ?= и ||= и когда нужно использовать его по сравнению с другим?

Ответ 1

? и || проверяют совершенно разные (но перекрывающиеся) условия.

Оператор || работает точно так же, как в JavaScript, поэтому такие вещи, как 0 и '', являются ложными до ||; || проверяет правдивость в смысле JavaScript.

Оператор ? преобразуется в == null в JavaScript, поэтому a ? b является только b, когда a является null или undefined; ? проверяет определенность в смысле CoffeeScript.

Рассмотрим следующее:

for v in [false, 0, '', null, undefined, 6]
    do (v) ->
        a = v
        a ||= 'pancakes'
        console.log("#{v} ||= 'pancakes':", a)

for v in [false, 0, '', null, undefined, 6]
    do (v) ->
        a = v
        a ?= 'pancakes'
        console.log("#{v} ?= 'pancakes':", a)

Первый цикл даст вам пять блинов и один 6, второй цикл даст вам false, 0, '', два блина и 6.

Демо: http://jsfiddle.net/ambiguous/PdLDe/1/

Итак, если вам нужно только поведение JavaScript-стиля (т.е. 0, false и ''), вы, вероятно, захотите ||=. Если вы хотите пропустить только null и undefined, тогда вы хотите ?=.