Operador ternário abreviado de Javascript

102

Eu sei que no php 5.3 em vez de usar esta sintaxe de operador ternário redundante:

startingNum = startingNum ? startingNum : 1

... podemos usar uma sintaxe abreviada para nossos operadores ternários, quando aplicável:

startingNum = startingNum ?: 1

E eu sei sobre o operador ternário em javascript:

startingNum = startingNum ? startingNum : 1

... mas existe uma abreviação?

Web designer
fonte

Respostas:

175
var startingNumber = startingNumber || 1;

Algo parecido com o que você está procurando, onde o padrão é indefinido?

var foo = bar || 1; // 1
var bar = 2;
foo = bar || 1;     // 2

A propósito, isso funciona para muitos cenários, incluindo objetos:

var foo = bar || {}; // secure an object is assigned when bar is absent
Brad Christie
fonte
Na verdade, está saltando esta manhã. Corrigido, mas obrigado por notar.
Brad Christie
1
Você não quer dizer em ||vez de ???
Rocket Hazmat
2
Obrigado! Você acertou em cheio. Na verdade, estou usando um objeto neste caso. :)
Web_Designer
8
Para quem está curioso, isso funciona porque o ||operador JS não retorna verdadeiro ou falso, ele retorna o primeiro valor 'verdadeiro'. Digamos que você tem val0e val1como undefined, e val2é 2, val3é 3. val0 || val1 || val2 || val3retornará 2, pois é o primeiro valor 'verdadeiro'.
Jake T.
2
Este idioma não é um antipadrão? E se você passar 0 ou string vazia, a expressão 'OU' irá ignorá-lo e usar o valor padrão onde você realmente queria 0 ou string vazia.
Paul Trzyna
24

|| retornará o primeiro valor verdadeiro que encontrar e, portanto, pode ser usado como um operador de coalescência, semelhante ao do C # ??

startingNum = startingNum || 1;
Adam Rackis
fonte
Gosto da sua explicação mais do que das outras
ajax333221
12

Sim existe:

var startingNum = startingNum || 1;

Em geral, expr1 || expr2funciona da seguinte forma (conforme mencionado pela documentação ):

Retorna expr1se puder ser convertido para true; caso contrário, retorna expr2. Portanto, quando usado com Booleanvalores, ||retorna truese qualquer operando for true; se ambos forem false, retorna false.

Tadeck
fonte
Não é mais correto dizer if a is truthyvs. if a is evaluated to true?
JaredPar
3
@JaredPar: Para evitar ambiguidade, substituí minha explicação detalhada original pela da Mozilla Developer Network. Deve ser menos ambíguo.
Tadeck de
2
var startingNum = startingNum || 1;

Nesse caso, você pode usar o operador OR.

Daniel
fonte
2
startingNum = startingNum || 1

Se você tem uma condição com nulo, como

startingNum = startingNum ? startingNum : null

você pode usar '&&'

startingNum = startingNum && startingNum
a2441918
fonte
Mas não será anything && nullavaliado como nulo a menos que anythingseja falso?
Petruza
Sim, se algo for verdadeiro, será avaliado como nulo. Se for falso, avalia o valor
falso
1

As respostas acima estão corretas. Em JavaScript, a seguinte declaração:

startingNum = startingNum ? otherNum : 1

pode ser expresso como

startingNum = otherNum || 1

Outro cenário não coberto aqui é se você deseja que o valor retorne falso quando não houver correspondência. A abreviação de JavaScript para isso é:

startingNum = startingNum ? otherNum : 0

Mas pode ser expresso como

startingNum = startingNum && otherNum

Só queria cobrir outro cenário, caso outros estivessem procurando uma resposta mais generalizada.

John Pace
fonte
existe uma abreviação para algo assim: x = innerWidth * 0.0375 > 24 ? innerWidth * 0.0375 : 24???
oldboy
@Anthony Não, porque innerWidth * 0.0375 > 24difere da if trueparte que é innerWidth * 0.0375. A abreviação só pode ser usada se expression to be evaluatede if trueforem os mesmos valores. Mesmo porque você não seria capaz de taquigrafar x = someBoolean ? 'Heck yea!' : 'No way!'.
deedub
@deedub bem, na verdade, há uma "abreviação" (se você pudesse chamá-la assim) que seriaMath.max(innerWidth * 0.0375, 24)
oldboy,
@Anthony Você não o chamaria assim;) Mas Math.maxfunciona melhor do que um operador ternário em seu caso de uso.
deedub
1
" startingNum = startingNum ? otherNum : 1pode ser expresso como startingNum = otherNum || 1" está errado. acabei de testar isso
oldboy
0

Para fazer um ternário como:

boolean_condition ? true_result : false_result

em javascript, você pode fazer:

(boolean_condition && true_result ) || false_result;

Exemplo:

(true && 'green') || 'red';
=> "green"
(false && 'green') || 'red';
=> "red"
xxjjnn
fonte
muuuito x = innerWidth * 0.0375 > 24 ? innerWidth * 0.0375 : 24se tornaria (innerWidth * 0.0375 > 24 && innerWidth * 0.0375) || 24?? Existe um atalho, para que eu não tenha que repetir innerWidth * 0.0375, a não ser atribuí-lo a uma variável ??
oldboy
1
Nesse caso, Math.max( innerWidth * 0.0375 , 24 )funcionaria com elegância. Para um caso mais geral, seria bom criar um método descritivo chamado, por exemplo, 'somethingifiedInnerWidth', que melhora a legibilidade, em vez de criar uma variável. Embora em alguns casos seja mais legível ter uma variável (com aquele nome descritivo), no futuro a pergunta 'por que ela é multiplicada por isso?' não é gerado.
xxjjnn
wow nem sabia que você poderia fornecer um segundo argumento para Math.max. solução super elegante !!
oldboy