Todos los valores de falsey en JavaScript

215

¿Cuáles son los valores en JavaScript que son 'Falsey-' , lo que significa que se evalúan como falso en expresiones como if(value), value ?y !value?


Ya hay algunas discusiones sobre el propósito de los valores de falsey en Stack Overflow , pero no hay una respuesta completa exhaustiva que enumere cuáles son todos los valores de falsey.

No pude encontrar ninguna lista completa en MDN JavaScript Reference , y me sorprendió descubrir que los mejores resultados al buscar una lista completa y autorizada de valores de falsey en JavaScript fueron artículos de blog, algunos de los cuales tenían omisiones obvias (por ejemplo, NaN), y ninguno de los cuales tenía un formato como el de Stack Overflow donde se podían agregar comentarios o respuestas alternativas para señalar peculiaridades, sorpresas, omisiones, errores o advertencias. Entonces, parecía tener sentido hacer uno.

user56reinstatemonica8
fuente
1
@tibos blog.stackoverflow.com/2011/07/…
user56reinstatemonica8
55
dorey.github.io/JavaScript-Equality-Table es un gran recurso y tiene una if()pestaña para la veracidad.
cloudfeet
44
Wow, realmente útil, gracias! [[]] == ""pero [] != []? Me duele la cabeza ...
user56reinstatemonica8
La especificación ECMA 262 detalla estas reglas de comparación, específicamente las secciones 11.9.1 a 11.9.6: ecma-international.org/ecma-262/5.1/#sec-11.9.3 Sería bueno si actualizara su respuesta para incluir esta referencia , ya que proporciona las reglas sobre cómo se hacen (se supone que deben hacerse) las determinaciones verdadero / falso.
Shaun Wilson

Respuestas:

367

Valores de Falsey en JavaScript

"Falsey" simplemente significa que la ToBooleanfunción interna de JavaScript regresa false. ToBooleansubyace !value, value ? ... : ...;y if (value). Aquí está su especificación oficial (borrador de trabajo 2020) (los únicos cambios desde la primera especificación de ECMAscript en 1997 son la adición de los símbolos de ES6 , que siempre son verdaderos y BigInt, mencionados anteriormente:

Indefinido: Devuelve falso.  Nulo: devuelve falso.  Booleano: argumento de retorno.  Número: si el argumento es +0, -0 o NaN, devuelve falso;  de lo contrario, devuelve verdadero.  Cadena: si el argumento es la cadena vacía (su longitud es cero), devuelve falso;  de lo contrario, devuelve verdadero.  BigInt: si el argumento es 0n, devuelve falso;  de lo contrario, devuelve verdadero.  Símbolo: Devuelve verdadero.  Objeto: Devuelve verdadero.


Comparaciones con ==(igualdad suelta)

Vale la pena hablar sobre las comparaciones sueltas de== los valores falsos , que usan ToNumber()y pueden causar cierta confusión debido a las diferencias subyacentes. Efectivamente forman tres grupos:

  • false, 0, -0, "", '' todos coinciden con ==
    • por ejemplo false == "", '' == 0y por lo tanto4/2 - 2 == 'some string'.slice(11);
  • null, undefined juntar con ==
    • por ejemplo, null == undefinedperoundefined != false
    • También vale la pena mencionar que, si bien typeof nulldevuelve 'object', nonull es un objeto, este es un error / peculiaridad de larga data que no se corrigió para mantener la compatibilidad. No es un objeto verdadero, y los objetos son verdaderos (excepto por esa "violación intencional" document.allcuando Javascript se implementa en HTML)
  • NaN no coincide con nada, con ==o ===, ni siquiera consigo mismo
    • por ejemplo NaN != NaN, NaN !== NaN, NaN != false,NaN != null

Con "igualdad estricta" ( ===), no existen tales agrupaciones. Sólo false === false.

Esta es una de las razones por las que muchos desarrolladores y muchas guías de estilo (por ejemplo, standardjs ) prefieren ===y casi nunca usan ==.


Valores de verdad que realmente == false

"Verdad" simplemente significa que la ToBooleanfunción interna de JavaScript regresa true. Una peculiaridad de Javascript a tener en cuenta (y otra buena razón para preferir ===sobre ==): es posible que un valor sea verdadero ( ToBooleanretornos true), pero también == false.

Puede pensar que if (value && value == false) alert('Huh?')es una imposibilidad lógica que no podría suceder, pero lo hará, para:

  • "0"y '0'- son cadenas no vacías, que son verdaderas, pero Javascript ==coincide con números con cadenas equivalentes (por ejemplo 42 == "42"). Puesto que 0 == false, si "0" == 0, "0" == false.
  • new Number(0)y new Boolean(false)- son objetos, que son verdaderos, pero ==ve sus valores, cuáles == false.
  • 0 .toExponential(); - un objeto con un valor numérico equivalente a 0
  • Cualquier construcción similar que le dé un valor de falsa igualdad envuelto en un tipo que sea verdadero
  • [], [[]]Y [0](gracias cloudfeet para el enlace de Igualdad JavaScript Tabla )

Algunos valores más verdaderos

Estos son solo algunos valores que algunas personas podrían esperar ser falsos, pero en realidad son verdaderos.

  • -1 y todos los números negativos distintos de cero
  • ' ', " ", "false", 'null'... todas las cadenas no vacías, incluyendo cadenas que son simplemente los espacios en blanco
  • Cualquier cosa de typeof, que siempre devuelve una cadena no vacía, por ejemplo:

  • Cualquier objeto (excepto esa "violación intencional" document.allen los navegadores; recuerde que nullno es realmente un objeto a pesar de typeofsugerir lo contrario). Incluso:

    • {}
    • []
    • function(){}o () => {}(cualquier función, incluidas las funciones vacías)
    • Error y cualquier instancia de Error
    • Cualquier expresión regular
    • Cualquier cosa creada con new(incluyendo new Number(0)y new Boolean(false))
  • Cualquier símbolo

true, 1, "1"Y [1]de retorno truecuando se compara entre sí con ==.

user56reinstatemonica8
fuente
3
Para su información, lo que !, ify ?..:tienen en común es que ellos llaman el interior ToBooleanfunción del valor. La forma en que se comportan esos valores en el contexto de !, ifetc. ya está implícita en su nombre: son valores "falsos". Soy un poco de miedo de que otros lean la respuesta y piensan "Oh por lo que en este contexto ( !, if, ?...:), el valor es false, pero con !!, es true" , pero no entiendo el concepto subyacente. Otros dos puntos: 1) v ? true : falsees solo una forma detallada de !!v. 2) typeof siempre devuelve una cadena no vacía, lo cual es verdadero.
Felix Kling
1
Es decir, no tiene sentido mirar typeof nullo typeof undefinedespecíficamente. Se podría decir que las cadenas no vacías son verdaderas.
Felix Kling
1
Ya veo, pero esto no tiene nada que ver con la pregunta original;) ​​Agregar demasiada información algo relacionada pero no relevante podría ser bastante confuso para los lectores.
Felix Kling
55
Acabo de enterarme de que eso también document.alles falso .
Claudiu
3
Con respecto a la comparación suelta: debido a que los booleanos se convierten en números, x == falsese llamará a lo ToNumber(x)que es muy diferente de ToBoolean(x). Podría valer la pena explicarlo. También me di cuenta de que ya había comentado sobre esta respuesta hace años: D
Felix Kling
3

No te olvides de la cadena no vacía "false"que se evalúa comotrue

MrMcPlad
fuente
8
... y, por lo tanto, ¿no es un valor falso, que se solicitó?
Bergi
55
Touché. es un valor que se podría esperar a ser Falsey- y no es, lo que es todavía vale la pena ser consciente de, y creo, merece mención en una lista exhaustiva
MrMcPlad
44
Se agregó a la lista ... ¡pero no intentemos convertir esto en una lista completa de todos los posibles valores de verdad! Eso llevaría un tiempo:-)
user56reinstatemonica8
3

Solo para agregar a la lista de valores falsos de @ user568458:

  • Además del número entero 0, el número decimal 0.0, 0.00 o cualquier número cero también es un valor falso.

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

    Impresiones de fragmentos de código anteriores I am a falsy value

  • De manera similar, la representación hexadecimal del número 0 también es un valor falso como se muestra en el siguiente fragmento de código:

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

    El fragmento de código anterior se imprime nuevamente I am a falsy value.

RBT
fuente
77
JavaScript no tiene números enteros. 0, 0x0, 0.0Y 0.00son sólo diferentes literales para el mismo IEEE-754 64-bit de punto flotante de valor cero.
fredoverflow
1

Además del tema, a partir de ES2020 tenemos un nuevo valor que es falso, es BigInt zero (0n):

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

Entonces, con esto, ahora tenemos 7 valores "falsos" en total (sin incluir document.all como lo mencionó el usuario anteriormente, ya que es parte de DOM y no de JS).

GetMeARemoteJob
fuente
1
¡Agradable! Gracias, aún no había escuchado sobre eso, lo agregué a la lista grande con un enlace que acredita su respuesta por plantearlo
user56reinstatemonica8