O que é o operador de tubo duplo ( ||
)?
O operador de canal duplo ( ||
) é o operador lógicoOR
. Na maioria dos idiomas , funciona da seguinte maneira:
- Se o primeiro valor for
false
, ele verifica o segundo valor. Se for true
, ele retorna true
e se é false
, ele retorna false
.
- Se o primeiro valor for
true
, ele sempre retornará true
, independentemente do segundo valor.
Então, basicamente, funciona como esta função:
function or(x, y) {
if (x) {
return true;
} else if (y) {
return true;
} else {
return false;
}
}
Se você ainda não entende, veja esta tabela:
| true false
------+---------------
true | true true
false | true false
Em outras palavras, só é falso quando ambos os valores são falsos.
Como é diferente em JavaScript?
O JavaScript é um pouco diferente, porque é uma linguagem pouco digitada . Nesse caso, significa que você pode usar o ||
operador com valores que não são booleanos. Embora não faça sentido, você pode usar este operador com, por exemplo, uma função e um objeto:
(function(){}) || {}
O que acontece lá?
Se os valores não forem booleanos, o JavaScript fará uma conversão implícita em booleano . Isso significa que, se o valor for Falsey (por exemplo 0
, ""
, null
, undefined
(ver também Todos os valores Falsey no JavaScript )), que serão tratadas como false
; caso contrário, é tratado como true
.
Portanto, o exemplo acima deve dar true
, porque a função vazia é verdadeira. Bem, não. Retorna a função vazia. Isso ||
ocorre porque o operador do JavaScript não funciona como eu escrevi no começo. Funciona da seguinte maneira:
- Se o primeiro valor for falsey , ele retornará o segundo valor .
- Se o primeiro valor for verdadeiro , ele retornará o primeiro valor .
Surpreso? Na verdade, é "compatível" com o ||
operador tradicional . Pode ser escrito da seguinte forma:
function or(x, y) {
if (x) {
return x;
} else {
return y;
}
}
Se você passar um valor verdadeiro como x
, ele retornará x
, ou seja, um valor verdadeiro. Portanto, se você usá-lo posteriormente na if
cláusula:
(function(x, y) {
var eitherXorY = x || y;
if (eitherXorY) {
console.log("Either x or y is truthy.");
} else {
console.log("Neither x nor y is truthy");
}
}(true/*, undefined*/));
você recebe "Either x or y is truthy."
.
Se x
fosse falsey, eitherXorY
seria y
. Nesse caso, você obteria o "Either x or y is truthy."
if y
era verdade; caso contrário, você receberia "Neither x nor y is truthy"
.
A questão real
Agora, quando você souber como o ||
operador funciona, provavelmente poderá entender por si mesmo o que x = x || y
significa. Se x
é verdade, x
é atribuído a x
, então, na verdade, nada acontece; caso contrário, y
é atribuído a x
. É comumente usado para definir parâmetros padrão nas funções. No entanto, muitas vezes é considerada uma má prática de programação , porque impede que você passe um valor de falsey (que não é necessariamente undefined
ou null
) como parâmetro. Considere o seguinte exemplo:
function badFunction(/* boolean */flagA) {
flagA = flagA || true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
Parece válido à primeira vista. No entanto, o que aconteceria se você passasse false
como flagA
parâmetro (já que é booleano, ou seja, pode ser true
ou false
)? Isso se tornaria true
. Neste exemplo, não há nenhuma maneira para definir flagA
a false
.
Seria uma idéia melhor verificar explicitamente se flagA
é undefined
assim:
function goodFunction(/* boolean */flagA) {
flagA = typeof flagA !== "undefined" ? flagA : true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
Embora seja mais longo, sempre funciona e é mais fácil de entender.
Você também pode usar a sintaxe ES6 para os parâmetros de função padrão , mas observe que ela não funciona em navegadores mais antigos (como o IE). Se você deseja oferecer suporte a esses navegadores, transpile seu código com o Babel .
Consulte também Operadores lógicos no MDN .
falsy
, não APENASundefined
. A quantidade de vezes que eu vidoWeDoIt = doWeDoIt || true
, é suficiente para me fazer chorar. (ou seja,doWeDoIt
vai agora nunca seráfalse
)