Tantas respuestas haciendo la mitad del trabajo. Sí, !!X
podría leerse como "la veracidad de X [representada como booleana]". Pero !!
, en términos prácticos, no es tan importante para determinar si una sola variable es (o incluso si muchas variables son) verdadera o falsa. !!myVar === true
es lo mismo que simplemente myVar
. Comparar !!X
un booleano "real" no es realmente útil.
Con lo que se gana !!
es con la capacidad de verificar la veracidad de múltiples variables entre sí de manera repetible, estandarizada (y amigable con JSLint).
Simplemente casting :(
Es decir...
0 === false
es false
.
!!0 === false
es true
.
Lo anterior no es tan útil. if (!0)
te da los mismos resultados que if (!!0 === false)
. No puedo pensar en un buen caso para convertir una variable en booleana y luego compararla con una booleana "verdadera".
Vea "== y! =" En las instrucciones de JSLint (nota: Crockford está moviendo su sitio un poco; ese enlace puede morir en algún momento) por un poco sobre por qué:
Los operadores == y! = Escriben la coerción antes de comparar. Esto es malo porque hace que '\ t \ r \ n' == 0 sea verdadero. Esto puede enmascarar errores de tipo. JSLint no puede determinar de manera confiable si == se está utilizando correctamente, por lo que es mejor no usar == y! = En absoluto y usar siempre los operadores === y! == más confiables.
Si solo le importa que un valor sea verdadero o falso, utilice la forma abreviada. En vez de
(foo != 0)
sólo decir
(foo)
y en lugar de
(foo == 0)
decir
(!foo)
Tenga en cuenta que hay algunos casos poco intuitivos en los que un booleano se convertirá en un número ( true
se convierte en 1
y false
para 0
) al comparar un booleano con un número. En este caso, !!
podría ser mentalmente útil. Sin embargo, de nuevo, estos son casos en los que se compara un booleano no booleano con un booleano de tipo rígido, lo cual es un error grave. if (-1)
sigue siendo el camino a seguir aquí.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
Y las cosas se ponen aún más locas dependiendo de tu motor. WScript, por ejemplo, gana el premio.
function test()
{
return (1 === 1);
}
WScript.echo(test());
¡Debido a algunos cambios históricos de Windows , eso generará -1 en un cuadro de mensaje! ¡Pruébelo en un indicador de cmd.exe y vea! Pero WScript.echo(-1 == test())
aún así te da 0, o WScript false
. Apartar. Es horrible
Comparando la veracidad :)
Pero, ¿qué pasa si tengo dos valores que necesito verificar para verdades / falsidades iguales?
Finge que tenemos myVar1 = 0;
y myVar2 = undefined;
.
myVar1 === myVar2
es 0 === undefined
y es obviamente falso.
!!myVar1 === !!myVar2
es !!0 === !!undefined
y es verdad! La misma veracidad! (En este caso, ambos "tienen una verdad de falsedad").
Entonces, el único lugar en el que realmente necesitaría usar "variables de conversión booleana" sería si tuviera una situación en la que esté verificando si ambas variables tienen la misma veracidad, ¿verdad? Es decir, el uso !!
si es necesario para ver si son dos vars tanto Truthy o ambos Falsy (o no), es decir, de igual (o no) truthiness .
No puedo pensar en un gran caso de uso no ideado para esa mano abierta. ¿Quizás tiene campos "vinculados" en un formulario?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
Entonces, si tiene una verdad para ambos o una falsa para el nombre y la edad del cónyuge, puede continuar. De lo contrario, solo tiene un campo con un valor (o un matrimonio arreglado muy temprano) y necesita crear un error adicional en su errorObjects
colección.
EDITAR 24 oct 2017, 6 feb 19:
Bibliotecas de terceros que esperan valores booleanos explícitos
Aquí hay un caso interesante ... !!
podría ser útil cuando las bibliotecas de terceros esperan valores booleanos explícitos.
Por ejemplo, False en JSX (React) tiene un significado especial que no se desencadena en la falsedad simple. Si intentó devolver algo como lo siguiente en su JSX, esperando un int en messageCount
...
{messageCount && <div>You have messages!</div>}
... es posible que se sorprenda al ver que React se procesa 0
cuando tiene cero mensajes. Debe devolver explícitamente false para que JSX no se procese. La declaración anterior regresa 0
, que JSX representa felizmente, como debería. No se puede decir que no tenía Count: {messageCount && <div>Get your count to zero!</div>}
(o algo menos artificial).
Una solución consiste en la bangbang, que coacciona 0
a !!0
, que es false
:
{!!messageCount && <div>You have messages!</div>}
Los documentos de JSX sugieren que seas más explícito, que escribas un código de auto comentario y que uses una comparación para forzar un booleano.
{messageCount > 0 && <div>You have messages!</div>}
Me siento más cómodo manejando la falsedad con un ternario.
{messageCount ? <div>You have messages!</div> : false}
Mismo trato en Typecript: si tiene una función que devuelve un valor booleano (o está asignando un valor a una variable booleana), [generalmente] no puede devolver / asignar un valor booleano-y; Tiene que ser un booleano fuertemente tipado. Esto significa que si iff myObject
está fuertemente tipado , return !myObject;
funciona para una función que devuelve un valor booleano, pero return myObject;
no lo hace. Tiene que return !!myObject
coincidir con las expectativas de Typecript.
¿La excepción para el mecanografiado? Si myObject
fue un any
, está de vuelta en el Salvaje Oeste de JavaScript y puede devolverlo sin !!
, incluso si su tipo de retorno es booleano.
Tenga en cuenta que estas son convenciones JSX y mecanografiadas , no inherentes a JavaScript .
Pero si ve 0
mensajes extraños en su JSX renderizado, piense en una gestión falsa.