Todos os valores de falsey em JavaScript

215

Quais são os valores em JavaScript que são 'Falsey' , o que significa que eles avaliam como falsa em expressões como if(value), value ?e !value?


Já existem algumas discussões sobre o objetivo dos valores de falsey no Stack Overflow , mas nenhuma resposta completa e exaustiva lista quais são todos os valores de falsey.

Não consegui encontrar nenhuma lista completa no MDN JavaScript Reference e fiquei surpreso ao descobrir que os principais resultados ao procurar uma lista completa e autorizada de valores falsey no JavaScript eram artigos de blog, alguns dos quais tinham omissões óbvias (por exemplo, NaN), e nenhum deles tinha um formato como o Stack Overflow, onde comentários ou respostas alternativas podiam ser adicionados para apontar peculiaridades, surpresas, omissões, erros ou advertências. Então, parecia fazer sentido fazer um.

user56reinstatemonica8
fonte
1
@tibos blog.stackoverflow.com/2011/07/…
user56reinstatemonica8
5
dorey.github.io/JavaScript-Equality-Table é um ótimo recurso e possui uma if()guia para veracidade.
Cloudfeet
4
Uau, realmente útil, obrigado! [[]] == ""A [] != []minha cabeça dói ...
user56reinstatemonica8 /
A Especificação ECMA 262 detalha essas regras de comparação, especificamente as seções 11.9.1 a 11.9.6: ecma-international.org/ecma-262/5.1/#sec-11.9.3 Seria bom se você atualizasse sua resposta para incluir esta referência , pois fornece as regras de como as determinações verdadeiras / falsas são (supostamente) feitas.
Shaun Wilson

Respostas:

367

Valores de Falsey em JavaScript

"Falsey" significa simplesmente que a ToBooleanfunção interna do JavaScript retorna false. ToBooleansubjaz !value, value ? ... : ...;e if (value). Aqui está sua especificação oficial (esboço de trabalho para 2020) (as únicas alterações desde a primeira especificação ECMAscript em 1997 são a adição dos símbolos do ES6 , que são sempre verdadeiros e BigIntmencionados acima:

Indefinido: retorne falso.  Nulo: retorne falso.  Booleano: argumento de retorno.  Número: Se o argumento for +0, -0 ou NaN, retorne false;  caso contrário, retorne verdadeiro.  String: se o argumento for a String vazia (seu comprimento é zero), retorne false;  caso contrário, retorne verdadeiro.  BigInt: Se o argumento for 0n, retorne false;  caso contrário, retorne verdadeiro.  Símbolo: Retorno verdadeiro.  Objeto: Return true.


Comparações com ==(igualdade solta)

Vale a pena falar das comparações frouxas== dos valores falsos , que usam ToNumber()e podem causar alguma confusão devido às diferenças subjacentes. Eles formam efetivamente três grupos:

  • false, 0, -0, "", '' todos combinam com ==
    • por exemplo false == "", '' == 0e portanto4/2 - 2 == 'some string'.slice(11);
  • null, undefined combina com ==
    • por exemplo, null == undefinedmasundefined != false
    • Também vale a pena mencionar que, enquanto typeof nullretornos 'object', nullé não um objeto, este é um longa data bug / peculiaridade que não foi fixado, a fim de manter a compatibilidade. Não é um objeto verdadeiro, e os objetos são verdadeiros (exceto a "violação intencional" document.allquando o Javascript é implementado em HTML)
  • NaN não corresponde a nada, com ==ou ===, nem mesmo a si próprio
    • por exemplo NaN != NaN, NaN !== NaN, NaN != false,NaN != null

Com "igualdade estrita" ( ===), não existem tais agrupamentos. Só false === false.

Essa é uma das razões pelas quais muitos desenvolvedores e muitos guias de estilo (por exemplo, standardjs ) preferem ===e quase nunca usam ==.


Valores reais que realmente == false

"Verdade" significa simplesmente que a ToBooleanfunção interna do JavaScript retorna true. Um capricho do Javascript estar ciente de (e outra boa razão para preferir ===mais ==): é possível para um valor a ser truthy ( ToBooleanretornos true), mas também == false.

Você pode pensar que if (value && value == false) alert('Huh?')é uma impossibilidade lógica que não poderia acontecer, mas ocorrerá por:

  • "0"e '0'- são strings não vazias, que são verdadeiras, mas o Javascript ==combina números com strings equivalentes (por exemplo 42 == "42"). Desde 0 == false, se "0" == 0, "0" == false.
  • new Number(0)e new Boolean(false)- são objetos que são verdadeiros, mas ==vêem seus valores, quais == false.
  • 0 .toExponential(); - um objeto com um valor numérico equivalente a 0
  • Quaisquer construções semelhantes que fornecem um valor de igual falso envolvido em um tipo verdadeiro
  • [], [[]]e [0](obrigado cloudfeet pelo link JavaScript Equality Table )

Alguns valores mais verdadeiros

Esses são apenas alguns valores que algumas pessoas podem esperar ser falsey, mas são realmente verdadeiros.

  • -1 e todos os números negativos diferentes de zero
  • ' ', " ", "false", 'null'... todas as cadeias não vazias, incluindo cordas que são apenas espaços em branco
  • Qualquer coisa de typeof, que sempre retorna uma string não vazia, por exemplo:

  • Qualquer objeto (exceto a "violação intencional" document.allnos navegadores; lembre-se de que nullnão é realmente um objeto, apesar de typeofsugerir o contrário). Incluindo:

    • {}
    • []
    • function(){}ou () => {}(qualquer função, incluindo funções vazias)
    • Error e qualquer instância de Error
    • Qualquer expressão regular
    • Qualquer coisa criada com new(incluindo new Number(0)e new Boolean(false))
  • Qualquer símbolo

true, 1, "1"E [1]retorno truequando comparados uns com os outros com ==.

user56reinstatemonica8
fonte
3
FYI, o que !, ife ?..:têm em comum é que eles chamam o interno ToBooleanfunção do valor. Como esses valores se comportam no contexto de !, ifetc. já está implícito em seu nome: eles são valores "falsos". Eu sou um pouco de medo que os outros vão ler a resposta e pensar "Oh so neste contexto ( !, if, ?...:), o valor é false, mas com !!, é true" , mas não entendo o conceito subjacente. Dois outros pontos: 1) v ? true : falseé apenas uma maneira detalhada de !!v. 2) typeof sempre retorna uma string não vazia, que é verdadeira.
Felix Kling
1
typeof nullOu seja, não há nenhum ponto em olhar ou typeof undefinedespecificamente. Você poderia apenas dizer que strings não vazias são verdadeiras.
Felix Kling
1
Entendo, mas isso não tem nada a ver com a pergunta original;) ​​Adicionar informações demais, de certa forma relacionadas, mas não relevantes, pode ser um pouco confuso para os leitores.
Felix Kling #
5
Acabei de aprender que isso também document.allé falso .
Claudiu 26/02
3
Em relação à comparação simples: como os booleanos são convertidos em números, x == falsechamará o ToNumber(x)que é muito diferente de ToBoolean(x). Vale a pena explicar. Também acabei de notar que já comentei essa resposta há séculos: D
Felix Kling
3

Não se esqueça da string não vazia "false"que é avaliada comotrue

MrMcPlad
fonte
8
... e, portanto, não é um valor falso, o que foi solicitado?
Bergi 04/10/19
5
touché. é um valor que você pode esperar ser Falsey e não é, que ainda vale a pena estar ciente de, e eu acho, merece destaque em uma lista abrangente
MrMcPlad
4
Adicionado à lista ... mas não vamos tentar transformar isso em uma lista abrangente de todos os possíveis valores de verdade! Isso iria demorar um pouco:-)
user56reinstatemonica8
3

Apenas para adicionar à lista de valores falsos do @ user568458:

  • Além do número inteiro 0, o número decimal 0.0, 0.00 ou qualquer número zero também é um valor falso.

    var myNum = 0.0;
    if(myNum){
        console.log('I am a truthy value');
    }
    else {
        console.log('I am a falsy value');
    }

    Impressões de trechos de código acima I am a falsy value

  • Da mesma forma, a representação hexadecimal do número 0 também é um valor falso, conforme mostrado no trecho de código abaixo:

    var myNum = 0x0; //hex representation of 0
    if(myNum){
        console.log('I am a truthy value');
    }   
    else {
        console.log('I am a falsy value');
    }

    O trecho de código acima é impresso novamente I am a falsy value.

RBT
fonte
7
JavaScript não possui números inteiros. 0, 0x0, 0.0E 0.00são apenas diferentes literais para o mesmo IEEE-754 64-bit ponto flutuante valor zero.
Fredoverflow
1

Além do tópico, a partir do ES2020, temos um novo valor que é falso, é BigInt zero (0n):

0n == false // true
-0n == false // true

Portanto, com isso, agora temos 7 valores "falsy" no total (sem incluir document.all, como mencionado pelo usuário acima, pois faz parte do DOM e não JS).

GetMeARemoteJob
fonte
1
Agradável! Obrigado, eu não tinha ouvido falar sobre isso ainda, eu o adicionei à grande lista com um link que
credita