booleano en una declaración if

144

Hoy recibí un comentario sobre el código considerando la forma en que verifico si una variable es verdadera o falsa en una tarea escolar.

El código que había escrito era algo como esto:

var booleanValue = true;

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

Dijeron que era mejor / más ordenado escribirlo así:

var booleanValue = true;

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

La observación que obtuve sobre la parte "=== verdadero" fue que no era necesaria y podía crear confusión.

Sin embargo, mi idea es que es mejor verificar si la variable es booleana o no, especialmente porque Javascript es un lenguaje poco definido.

En el segundo ejemplo, una cadena también devolvería "algo";

Entonces mi pregunta; ¿Es mejor perder la parte "=== verdadero" en el futuro, o también es una buena práctica verificar el tipo de variable.

Editar: en mi código "real", el booleano representa si una imagen se ha eliminado o no, por lo que los únicos valores que boolValue debería tener es verdadero o falso.

0 y 1, por ejemplo, no deberían estar en esa variable.

DirkZz
fuente
44
es legible y una buena práctica usar ===
Piyas De
2
+1 para === true. ¡Evita la confusión!
Gashu
1
@gashu Considerar se [0] === trueevalúa como falso.
RestingRobot
1
@Jlange no debería? Por favor explique
gashu
Lo que quise decir con eso es que si simplemente quisiera verificar una existencia "verdadera", esa afirmación fallaría, aunque debería evaluar como verdadera ([0] se evalúa como verdadera pero no sin conversión de tipo). Realmente depende de lo que intente lograr con su declaración. Úselo === truecuando necesite asegurarse de que la condición sea exactamente igual a true.
RestingRobot

Respuestas:

222

En primer lugar, los hechos:

if (booleanValue)

Satisfacerá la ifdeclaración para cualquier valor verdadero de booleanValueincluir true, cualquier número que no sea cero, cualquier valor de cadena no vacío, cualquier referencia de objeto o matriz, etc.

Por otra parte:

if (booleanValue === true)

Esto solo satisfará la ifcondición si booleanValuees exactamente igual a true. Ningún otro valor de verdad lo satisfará.

Por otro lado, si haces esto:

if (someVar == true)

Entonces, lo que hará Javascript es escribir coacción true para que coincida con el tipo de someVary luego comparar las dos variables. Hay muchas situaciones en las que esto probablemente no sea lo que uno pretendería. Debido a esto, en la mayoría de los casos desea evitarlo ==porque hay un conjunto bastante largo de reglas sobre cómo JavaScript escribirá para obligar a dos cosas a ser del mismo tipo y, a menos que comprenda todas esas reglas y pueda anticipar todo lo que el intérprete de JS podría hacer cuando dados dos tipos diferentes (que la mayoría de los desarrolladores de JS no pueden), probablemente desee evitar por ==completo.

Como ejemplo de lo confuso que puede 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 

Por el valor 2, pensaría que 2es un valor verdadero, por lo que se compararía favorablemente true, pero no es así como funciona la coerción de tipo. Está convirtiendo el valor de la mano derecha para que coincida con el tipo del valor de la mano izquierda, por lo que su conversióntrue en el número 1para que esté comparando, lo 2 == 1que ciertamente no es lo que probablemente pretendía.

Entonces, comprador tenga cuidado. Es probable que sea mejor evitar== en casi todos los casos, a menos que conozca explícitamente los tipos que comparará y sepa cómo funcionan todos los algoritmos de coerción de tipos posibles.


Por lo tanto, realmente depende de los valores esperados booleanValuey de cómo desea que funcione el código. Si sabe de antemano que solo tendrá una trueofalse valor , entonces compárelo explícitamente con

if (booleanValue === true)

es solo código extra e innecesario y

if (booleanValue)

es más compacto y posiblemente más limpio / mejor.

Si, por otro lado, no sabe qué booleanValuepodría ser y desea probar si realmente está configurado truesin otras conversiones de tipo automáticas permitidas, entonces

if (booleanValue === true)

No solo es una buena idea, sino que se requiere.


Por ejemplo, si observa la implementación de .on()jQuery, tiene un valor de retorno opcional. Si vuelve la devolución de llamada false, jQuery detendrá automáticamente la propagación del evento. En este caso específico, ya que jQuery quiere propagación parada sólo si falsefue devuelto, comprueban el valor de retorno para explícitamente === falseporque no quieren undefinedo 0o ""o cualquier otra cosa que se escriba automáticamente-convertir en false para satisfacer también la comparación.

Por ejemplo, aquí está el código de devolución de llamada de manejo de eventos jQuery:

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

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

Puedes ver que jQuery está buscando explícitamente ret === false .

Pero, también hay muchos otros lugares en el código jQuery donde una verificación más simple es apropiada dado el deseo del código. Por ejemplo:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...
jfriend00
fuente
He estado pensando en esta pregunta por un tiempo, pero no he tenido la oportunidad de encontrar a alguien a quien preguntar. Te agradecería si pudieras echar un vistazo. stackoverflow.com/questions/32615466/…
mmm
Esta respuesta no es completamente correcta. 'x == verdadero' no será verdadero para números que no sean cero.
Teemoh
@Teemoh: no entiendo tu comentario. Ver jsfiddle.net/jfriend00/89h8d8tm .
jfriend00
1
Solo quiero decir que 'if (x)' no es lo mismo que 'if (x == verdadero)', como escribió en el primer párrafo de su respuesta. 'if (x)' convertirá explícitamente 'x' a su representación booleana. 'if (x == true)' usará el algoritmo de comparación abstracta de EcmaScript. Usted escribió que 'if (x == true)' será verdadero para cualquier número distinto de cero o cadena no vacía o cualquier objeto. Esto es simplemente incorrecto. Si ejecuto su ejemplo con 2 en lugar de 1, no funcionará.
Teemoh
2
@Teemoh: veo tu punto. Respuesta corregida y aclarada y agregué una sección sobre coerción de tipo con un ejemplo que muestra cómo puede hacer cosas inesperadas.
jfriend00
40

Si escribe:, if(x === true)será verdadero solo para x = verdadero

Si escribe:, if(x)será verdadero para cualquier x que no sea: '' (cadena vacía), falso, nulo, indefinido, 0, NaN.

karaxuna
fuente
(cadena vacía), falso, nulo, indefinido, 0, NaN
Oliboy50
No te olvides NaNy -0.
haykam
8

En el simple "if", la variable se convertirá en un Boolean y usará toBoolean en el 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.

Pero la comparación con === no tiene ningún tipo de coerción, por lo que deben ser iguales sin coerción.

Si está diciendo que el objeto puede no ser un booleano, entonces puede que tenga que considerar algo más que verdadero / falso.

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

Depende de su caso de uso. Puede tener sentido verificar el tipo también, pero si es solo una bandera, no lo hace.

Ven
fuente
La ===comparación no realiza coerción de tipo. Por lo tanto, el código del OP efectivamente prueba el tipo de bandera. Solo tiene éxito si el valor es booleano y es verdadero.
Jesse Hallett el
Déjame reformular. Si sabes que será verdadero o falso, no importa.
Ven
5

En general, es más limpio y sencillo omitir el === true.

Sin embargo, en Javascript, esas declaraciones son diferentes.

if (booleanValue)ejecutará si booleanValuees Truthy - que no sea nada 0, false, '', NaN, null, y undefined.

if (booleanValue === true)solo se ejecutará si booleanValuees exactamente igual a true.

SLaks
fuente
De eso es precisamente de lo que quiero estar seguro, incluso cuando solo quiero que boolValue sea verdadero o falso. La variable se establece en verdadero / falso varias veces en el código. Sé eso cuando escribo el código, pero si lo reviso nuevamente un año después, entonces es solo un gran signo de interrogación a menos que vuelva a leer todo ¿no?
DirkZz
@aldanux: ¡Vaya! Me refería ''.
SLaks
4

El (===)operador de identidad se comporta de manera idéntica al (==)operador de igualdad , excepto que no se realiza la conversión de tipo, y los tipos deben ser iguales para ser considerados iguales.

SOFTWARE Apollo
fuente
Tu última oración está mal. Pruebe sus dos afirmaciones if (booleanValue)y if (booleanValue==true)cuándo booleanValuees 2. Esas dos declaraciones no te dan el mismo resultado.
jfriend00
Interesante. Tomaré tu palabra por ello. Estaba pensando en el mundo ObjC / C / C ++, en JS, supongo que estás en lo correcto, ya que los tipos de datos en JS se pueden cambiar y 2 == verdadero no cuantificará el if entonces.
SOFTWARE Apollo
1
Vea mi respuesta anterior para este ejemplo específico. Tiene que ver con cómo Javascript realiza la conversión automática de tipos para comparar dos valores de diferentes tipos.
jfriend00
3

Dado que el valor marcado es Booleanpreferible usarlo directamente para menos codificación y en absoluto hizo lo mismo==true

Alyafey
fuente
2

Dado que ya se inicializó claramente como bool, creo ===que no se requiere operador.

Soleado
fuente
2

Si la variable solo puede tomar valores booleanos, entonces es razonable usar la sintaxis más corta.

Si potencialmente se le pueden asignar otros tipos, y necesita distinguir truede 1o "foo", entonces debe usar === true.

Barmar
fuente
2

Creo que tu razonamiento es sólido. Pero en la práctica he descubierto que es mucho más común omitir la ===comparación. Creo que hay tres razones para eso:

  1. Por lo general, no se agrega al significado de la expresión, es decir, en los casos en que se sabe que el valor es booleano de todos modos.
  2. Debido a que existe una gran cantidad de incertidumbre tipo en JavaScript, obligando a una verificación de tipos tiende a morder cuando recibe un inesperado undefinedo nullvalor. A menudo solo desea que su prueba falle en tales casos. (Aunque trato de equilibrar esta vista con el lema "falla rápido").
  3. A los programadores de JavaScript les gusta jugar rápido y suelto con tipos, especialmente en expresiones booleanas, porque podemos hacerlo.

Considere este ejemplo:

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

if (normalized) {
    submitInput(normalized);
}

Creo que este tipo de código no es infrecuente. Se ocupa de los casos en los getInput()rendimientos undefined, nullo una cadena vacía. Debido a las dos evaluaciones booleanas, submitInput()solo se llama si la entrada dada es una cadena que contiene caracteres que no son espacios en blanco.

En JavaScript &&devuelve su primer argumento si es falso o su segundo argumento si el primer argumento es verdadero; así normalizedserá undefinedsi someStringno estaba definido y así sucesivamente. Eso significa que ninguna de las entradas a las expresiones booleanas anteriores son en realidad valores booleanos.

Sé que muchos programadores que están acostumbrados a una fuerte verificación de tipos se avergüenzan al ver un código como este. Pero tenga en cuenta que la aplicación de una tipificación fuerte probablemente requeriría verificaciones explícitas nullo undefinedvalores, lo que saturaría el código. En JavaScript eso no es necesario.

Jesse Hallett
fuente
1

Esto depende Si le preocupa que su variable pueda terminar como algo que se resuelve como VERDADERO. Entonces la comprobación dura es imprescindible. De lo contrario, depende de usted. Sin embargo, dudo que la sintaxis whatever == TRUEpueda confundir a alguien que supiera lo que estaban haciendo.

usumoio
fuente
1

En Javascript, la idea de booleano es bastante ambigua. Considera esto:

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

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

Por lo tanto, cuando está utilizando una instrucción if (o cualquier otra instrucción de control), no es necesario utilizar un tipo "booleano" var. Por lo tanto, en mi opinión, la parte "=== verdadero" de su declaración es innecesaria si sabe que es booleana, pero absolutamente necesaria si su valor es una var "verdadera" ambigua. Puede encontrar más sobre booleanos en javscript aquí .

DescansandoRobot
fuente
1

También se puede probar con un objeto booleano, si necesita probar un objeto error={Boolean(errors.email)}

Igor Pavlenko
fuente