Operador ternário Javascript vs. ||

17

Eu estava dando uma olhada em algum código node.js. anteriormente e notei que o cara que o escreveu parecia favorecer a seguinte sintaxe:

var fn = function (param) {
    var paramWithDefault = null == param ? 'Default Value' : param;
}

Sobre o que considero mais conciso:

var fn = function (param) {
    var paramWithDefault = param || 'Default Value';
}

Fiquei me perguntando se o segundo formulário é realmente mais sintaxe JavaScript socialmente aceitável, já o vi na natureza mais vezes do que o operador ternário para esse fim.

Percebo que, no primeiro exemplo, ele está usando o duplo igual (não o triplo igual), o que significa que ele contará "indefinido" como nulo, o que reduziria um impacto que eu poderia pensar. No entanto, eu li em vários lugares que == é um operador bastante ruim em JavaScript (o JSLint é muito contra, IIRC).

Ed James
fonte
2
Comentaristas : os comentários destinam-se a buscar esclarecimentos, não a discussões prolongadas. Se você tiver uma solução, deixe uma resposta. Se sua solução já estiver publicada, faça um voto positivo. Se você quiser discutir esta questão com outras pessoas, use o bate-papo . Veja o FAQ para mais informações.

Respostas:

17

Como esse código seria avaliado como 'Valor padrão' sempre que você passasse 0, "", false ou algum outro valor falso.

function fn(param) {
  var paramWithDefault = param || 'Default Value';
  return paramWithDefault;
}

Talvez você não se preocupe com o modo como você usa essa função específica, mas é um padrão ruim a ser evitado quando você se importa em passar coisas como cadeias vazias ou 0 ou um booleano.

Peter Smith
fonte
você só deve usar uma coalescência nula em um objeto e, se um objeto estiver definido, isso não funcionará. Com talvez a exceção da string vazia.
Malfist
4
A comparação zero é um bom ponto, que pode ser bastante inesperado.
Ed James
1
+1 - esse problema é precisamente o motivo pelo qual o Python (eventualmente) adicionou a sintaxe "x se y else z". Essas semânticas para operadores lógicos são bastante comuns e os mesmos erros comuns tendem a surgir sempre que idiomas dependem deles para fazer o trabalho de operadores de seleção condicional.
Steve314 8/08
apenas não esqueça de colocar suas construções entre parênteses, se você usá-las juntamente com a concatenação de strings var txt = 'Hello, ' + (user_name||'User') + '!';funcionará, mas sem parênteses - você receberá undefined. jsfiddle.net/4mFAB/1
c69
7

O que você realmente precisa é de um operador de coalescência nula. Mas, visto que o javascript realmente não tem um, os programadores geralmente usam '||' para substituí-lo.

No entanto, ambos são perfeitamente razoáveis. Para aqueles que não entendem o que é um operador de coalescência nula, provavelmente é mais provável que o operador ternário seja entendido.

Malfist
fonte
Outro operador relacionado é o operador Icon escrito IIRC "else". Isso reconhece um resultado especial de "falha" do primeiro argumento e usa o segundo argumento nesse caso como uma alternativa. Eu meio que gostaria que os Pythons "x se y else z" fossem implementados usando dois operadores separados - um operador de asserção binária "if" e um operador "else" do tipo Icon - com esses dois operadores sendo utilizáveis ​​independentemente. No entanto, o Icon não suportava esse estilo, mas fazia algo bizarro com operadores relativos.
Steve314
@ Steve314: Python tem algo que você queria: um operador else separado [false-part, true-part]com um operador separado se [..][bool(condition)]combinado [false-part, true-part][bool(condition)]. Se você quer um comportamento preguiçoso, pode simplesmente criar a parte verdadeira e falsa.
Lie Ryan
Versão do c # no MSDN
ruffin 04/04