booleano em uma instrução if

144

Hoje, recebi um comentário sobre código, considerando a maneira como verifico se uma variável é verdadeira ou falsa em uma tarefa da escola.

O código que eu escrevi era mais ou menos assim:

var booleanValue = true;

function someFunction(){
    if(booleanValue === true){
        return "something";
    }
}

Eles disseram que era melhor / mais puro escrever assim:

var booleanValue = true;

function someFunction(){
    if(booleanValue){
        return "something";
    }
}

A observação que recebi sobre a parte "=== true" foi que ela não era necessária e poderia criar confusão.

No entanto, minha ideia é que é melhor verificar se a variável é booleana ou não, especialmente porque o Javascript é uma linguagem com folga.

No segundo exemplo, uma string também retornaria "algo";

Então minha pergunta; É melhor perder a parte "=== true" no futuro ou é uma boa prática verificar também o tipo da variável.

Edit: No meu código "real", o booleano representa se uma imagem foi excluída ou não; portanto, os únicos valores que o boolValue deve ter é verdadeiro ou falso.

0 e 1, por exemplo, não devem estar nessa variável.

DirkZz
fonte
4
é legível e é uma boa prática usar === #
Piyas De
2
+1 para === true. Evita confusão !!
Gashu # 13/13
1
@gashu Considere [0] === trueavalia como false.
RestingRobot
1
@Jlange não deveria? Por favor, explique
gashu 13/03/2019
O que eu quis dizer com isso é que, se você simplesmente quisesse verificar a existência de uma "verdade", essa declaração falharia, embora devesse ser avaliada como verdadeira ([0] avalia como verdadeira, mas não sem conversão de tipo). Realmente depende do que você está tentando realizar com sua declaração. Use === truequando precisar garantir que a condição seja exatamente igual a true.
RestingRobot

Respostas:

222

Primeiro, os fatos:

if (booleanValue)

Satisfará a ifdeclaração para qualquer valor verdadeiro de booleanValueinclusão true, qualquer número diferente de zero, qualquer valor de string não vazio, qualquer referência a objeto ou matriz, etc ...

Por outro lado:

if (booleanValue === true)

Isso só satisfará a ifcondição se booleanValuefor exatamente igual a true. Nenhum outro valor verdadeiro o satisfará.

Por outro lado, se você fizer isso:

if (someVar == true)

Em seguida, o que o Javascript fará é digitar coerce truepara corresponder ao tipo de someVare comparar as duas variáveis. Existem muitas situações em que isso provavelmente não é o que se pretenderia. Por isso, na maioria dos casos, você deseja evitar, ==porque há um conjunto de regras bastante longo sobre como o Javascript digitar coagirá duas coisas para serem do mesmo tipo e, a menos que você entenda todas essas regras e possa antecipar tudo o que o interpretador JS pode fazer quando dados dois tipos diferentes (que a maioria dos desenvolvedores de JS não pode), você provavelmente deseja evitar ==completamente.

Como um exemplo de quão confuso pode ser:

var x;

x = 0;
console.log(x == true);   // false, as expected
console.log(x == false);  // true as expected

x = 1;
console.log(x == true);   // true, as expected
console.log(x == false);  // false as expected

x = 2;
console.log(x == true);   // false, ??
console.log(x == false);  // false 

Para o valor 2, você pensaria que 2é um valor verdadeiro para que ele se comparasse favoravelmente com true, mas não é assim que a coerção de tipos funciona. Ele está convertendo o valor da mão direita para coincidir com o tipo do valor da mão esquerda e, portanto, está convertendo truepara o número, 1para comparar, o 2 == 1que certamente não é o que você provavelmente pretendia.

Então, cuidado com o comprador. Provavelmente, é melhor evitar isso ==em quase todos os casos, a menos que você saiba explicitamente os tipos que irá comparar e saiba como todos os algoritmos de coerção de tipos possíveis funcionam.


Portanto, depende realmente dos valores esperados booleanValuee de como você deseja que o código funcione. Se você sabe de antemão que isso só terá um valor trueou false, compare-o explicitamente com

if (booleanValue === true)

é apenas código extra e desnecessário e

if (booleanValue)

é mais compacto e sem dúvida mais limpo / melhor.

Se, por outro lado, você não sabe o que booleanValuepode ser e deseja testar se está realmente definido como truesem outras conversões de tipo automáticas permitidas,

if (booleanValue === true)

não é apenas uma boa ideia, mas necessária.


Por exemplo, se você observar a implementação .on()no jQuery, ele terá um valor de retorno opcional. Se o retorno de chamada retornar false, o jQuery interromperá automaticamente a propagação do evento. Nesse caso específico, como o jQuery deseja interromper a propagação SOMENTE se falsefor retornado, eles verificam a explicitação do valor de retorno === falseporque não querem undefinedou 0ou"" ou qualquer outra coisa que automaticamente converta o tipo em falso para também satisfazer a comparação.

Por exemplo, aqui está o código de retorno de chamada de manipulação de evento jQuery:

ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );

if ( ret !== undefined ) {
     event.result = ret;
     if ( ret === false ) {
         event.preventDefault();
         event.stopPropagation();
     }
 }

Você pode ver que o jQuery está procurando explicitamente ret === false.

Porém, também existem muitos outros lugares no código jQuery em que uma verificação mais simples é apropriada, dado o desejo do código. Por exemplo:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...
jfriend00
fonte
Estou pensando nessa questão há algum tempo, mas não tive a chance de encontrar alguém para perguntar. Eu apreciaria se você pudesse dar uma olhada. stackoverflow.com/questions/32615466/…
mmm
Esta resposta não está completamente correta. 'x == true' não será verdadeiro para números diferentes de zero.
Teemoh 25/06
@ Teemoh - Eu não entendo o seu comentário. Veja jsfiddle.net/jfriend00/89h8d8tm .
jfriend00
1
Eu só quero dizer que 'if (x)' não é o mesmo que 'if (x == true)', como você escreveu no primeiro parágrafo da sua resposta. 'if (x)' converterá explicitamente 'x' para sua representação booleana. 'if (x == true)' usará o algoritmo de comparação abstrata do EcmaScript. Você escreveu que 'if (x == true)' será verdadeiro para qualquer número diferente de zero, string não vazia ou qualquer objeto. Isso está errado. Se eu executar o seu exemplo com 2 em vez de 1, não funcionará.
Teemoh
2
@ Teemoh - Entendo o seu ponto. Resposta corrigida e esclarecida e adicionei uma seção sobre coerção de tipo com um exemplo que mostra como ele pode fazer coisas inesperadas.
jfriend00
40

Se você escrever if(x === true):, será verdadeiro apenas para x = true

Se você escrever if(x):, será verdadeiro para qualquer x que não seja: '' (sequência vazia), falso, nulo, indefinido, 0, NaN.

karaxuna
fonte
(string vazia), falso, nulo, indefinido, 0, NaN
Oliboy50
Não esqueça NaNe -0.
haykam
8

Na planície "se" a variável será coagida a um booleano e usa toBoolean no objeto: -

    Argument Type   Result

    Undefined       false
    Null            false
    Boolean         The result equals the input argument (no conversion).
    Number          The result is false if the argument is +0, 0, or NaN;
                    otherwise the result is true.
    String          The result is false if the argument is the empty 
                    String (its length is zero); otherwise the result is true.
    Object          true.

Mas a comparação com === não tem nenhum tipo de coerção, portanto, eles devem ser iguais sem coerção.

Se você está dizendo que o objeto pode até não ser um booleano, talvez seja necessário considerar mais do que verdadeiro / falso.

if(x===true){
...
} else if(x===false){
....
} else {
....
}
QuentinUK
fonte
5

Depende do seu caso. Pode fazer sentido verificar o tipo também, mas se for apenas uma bandeira, não será.

Ven
fonte
A ===comparação não executa coerção de tipo. Portanto, o código do OP efetivamente testa o tipo do sinalizador. Ele só será bem-sucedido se o valor for um booleano e for verdadeiro.
precisa
Deixe-me reformular. Se você sabe que será verdadeiro ou falso, não importa.
Ven
5

Em geral, é mais limpo e mais simples omitir o arquivo === true.

No entanto, em Javascript, essas instruções são diferentes.

if (booleanValue)será executado se booleanValueé truthy - outra coisa senão 0, false, '', NaN, null, e undefined.

if (booleanValue === true)só será executado se booleanValuefor precisamente igual a true.

SLaks
fonte
É exatamente disso que eu quero ter certeza, mesmo quando eu apenas quero que o boolValue seja verdadeiro ou falso. A variável é definida como true / false várias vezes no código. Eu sei que quando eu escrevo o código, mas se eu verificar o código novamente um ano depois, é apenas um grande ponto de interrogação, a menos que eu releia tudo certo?
DirkZz
@aldanux: Opa; Eu quis dizer ''.
SLaks
4

O (===)operador de identidade se comporta de maneira idêntica ao (==)operador de igualdade , exceto que nenhuma conversão de tipo é feita e os tipos devem ser os mesmos para serem considerados iguais.

Apollo SOFTWARE
fonte
Sua última frase está errada. Tente suas duas afirmações if (booleanValue)e if (booleanValue==true)quando booleanValuefor 2. Essas duas declarações não fornecem o mesmo resultado.
precisa saber é o seguinte
Interessante. Eu aceito sua palavra. Eu estava pensando no mundo ObjC / C / C ++, em JS, estou assumindo que você esteja correto, pois os tipos de dados em JS podem ser alterados e 2 == true não quantificará o que está ocorrendo.
Apollo SOFTWARE
1
Veja minha resposta acima para este exemplo específico. Tem a ver com a maneira como o Javascript faz a conversão automática de tipos para comparar dois valores de tipos diferentes.
precisa saber é o seguinte
3

Como o valor verificado é Booleanpreferível usá-lo diretamente para menos codificação e, ao mesmo tempo, fez o mesmo==true

Alyafey
fonte
2

Como você já inicializou claramente como bool, acho que o ===operador não é necessário.

Ensolarado
fonte
2

Se a variável puder apenas assumir valores booleanos, é razoável usar a sintaxe mais curta.

Se ele puder ser atribuído a outros tipos, e você precisar diferenciá-lo truede 1ou "foo", deverá usá-lo === true.

Barmar
fonte
2

Eu acho que seu raciocínio é sólido. Mas, na prática, descobri que é muito mais comum omitir a ===comparação. Eu acho que existem três razões para isso:

  1. Geralmente, não adiciona ao significado da expressão - é nos casos em que o valor é conhecido por ser booleano.
  2. Como há muita incerteza de tipo no JavaScript, forçar uma verificação de tipo tende a incomodá-lo quando você obtém um valor undefinedou um inesperado null. Freqüentemente, você só quer que seu teste falhe nesses casos. (Embora eu tente equilibrar essa visão com o lema "falhe rápido").
  3. Programadores de JavaScript gostam de jogar rápido e solto com tipos - especialmente em expressões booleanas - porque nós podemos.

Considere este exemplo:

var someString = getInput();
var normalized = someString && trim(someString);  
// trim() removes leading and trailing whitespace

if (normalized) {
    submitInput(normalized);
}

Eu acho que esse tipo de código não é incomum. Ele lida com casos onde getInput()os retornos undefined, nullou uma cadeia vazia. Devido às duas avaliações booleanassubmitInput() é chamado apenas se a entrada fornecida for uma sequência que contenha caracteres que não sejam espaços em branco.

Em JavaScript && retorna seu primeiro argumento se for falso ou seu segundo argumento se o primeiro argumento for verdadeiro; assim normalizedserá undefinedse someStringfoi indefinido e assim por diante. Isso significa que nenhuma das entradas para as expressões booleanas acima são realmente valores booleanos.

Eu sei que muitos programadores que estão acostumados a fortes checagens de verificação de tipo quando vêem códigos como este. Mas observe que a aplicação de digitação forte provavelmente exigiria verificações nullou undefinedvalores explícitos , o que desorganizaria o código. Em JavaScript, isso não é necessário.

Jesse Hallett
fonte
1

Isso depende Se você está preocupado com o fato de que sua variável pode acabar como algo que resolve como VERDADEIRO. Então, a verificação rigorosa é uma obrigação. Caso contrário, cabe a você. No entanto, duvido que a sintaxe whatever == TRUEpossa confundir quem sabe o que está fazendo.

usumoio
fonte
1

Em Javascript, a idéia de booleano é bastante ambígua. Considere isto:

 var bool = 0 
 if(bool){..} //evaluates to false

 if(//uninitialized var) //evaluates to false

Portanto, quando você está usando uma instrução if (ou qualquer outra instrução de controle), não é necessário usar um tipo "booleano" var. Portanto, na minha opinião, a parte "=== true" da sua declaração é desnecessária se você souber que é um booleano, mas absolutamente necessária se o seu valor for uma var ambígua "verdade". Mais sobre booleanos em javscript podem ser encontrados aqui .

RestingRobot
fonte
1

Também pode ser testado com objeto booleano, se você precisar testar um objeto error={Boolean(errors.email)}

Igor Pavlenko
fonte