Comparación de cadenas implícita, 0==”, pero 1==’1′

4 minutos de lectura

avatar de usuario
Diodeo – James MacFarlane

Estaba depurando algo y descubrí algo extraño en JavaScript:

alert(1=='') ==> false
alert(0=='') ==> true
alert(-1=='') ==> false

Tendría sentido que una comparación de cadenas implícita que 0 debería = ‘0’. Esto es cierto para todos los valores distintos de cero, pero ¿por qué no para cero?

Según la documentación de Mozilla sobre Operadores de comparación de Javascript

Si los dos operandos no son del mismo tipo, JavaScript convierte los operandos y luego aplica una comparación estricta. Si alguno de los operandos es un número o un valor booleano, los operandos se convierten en números; si cualquiera de los operandos es una cadena, el otro se convierte en una cadena

Lo que realmente sucede es que las cadenas se están convirtiendo en números. Por ejemplo:

1 == '1' se convierte 1 == Number('1') se convierte 1 == 1: true

Entonces prueba con este:
1 == '1.' se convierte 1 == Number('1.') se convierte 1 == 1: true
Si se estuvieran convirtiendo en cuerdas, entonces obtendrías '1' == '1.'lo cual sería falso.

Sucede que Number('') == 0por lo tanto 0 == '' es verdad

Cuando javascript realiza conversiones de tipo implícitas, el literal de cadena vacío coincidirá con el entero 0. Haga su comparación de esta manera y obtendrá el resultado esperado:

alert(1==='') ==> false
alert(0==='') ==> false
alert(-1==='') ==> false

avatar de usuario
Cristóbal

ECMA-262, 3.ª edición, 11.9.3 sobre x == ypaso 16:

Si Type(x) es Number y Type(y) es String, devuelve el resultado de la comparación x == ToNumber(y).

La cadena vacía '' se convierte en 0 antes de la comparación.

  • @RoBorg: la vinculación no funciona con archivos PDF, y buscar en Google ECMA-262 y hacer clic en el primer enlace no es un gran inconveniente …

    – Cristóbal

    20 de enero de 2009 a las 19:36

  • @Christoph tampoco está buscando en Google “operador de igualdad de JavaScript”, pero ese no es el punto

    – Greg

    20 de enero de 2009 a las 21:34

  • @RoBorg: mi punto era que es imposible vincular en profundidad a la sección correcta, y proporcionar un vínculo a un documento de estándares fácilmente disponible no es realmente una de mis prioridades, ¿y qué? es ¿tu punto?

    – Cristóbal

    20 de enero de 2009 a las 21:47

Este es solo uno de los mutiladores verdaderamente horribles que entraron en el compromiso de JavaScript. ” y 0 son ambos valores no inicializados (igual a falso booleano) y, por lo tanto, iguales.

Para protegerse de errores extraños como este, es mejor usar siempre el operador ===.

Javascript, como PHP, tiene un tipo débil*. Entonces, cuando compara 0 con ”, el motor JS los convierte a un tipo de datos similar. Dado que 0 y ” ambos equivalen a booleano (falso), “falso == falso” es verdadero.

*Los lenguajes de tipo débil no requieren que las variables sean de ningún tipo de datos específico, por lo que puede configurar una variable como una cadena, cambiarla a int, float y volver a la cadena sin que el procesador arroje errores.

  • +1 Muy bien: ¿sabe cómo decide el motor a qué tipo de datos convertir? Obviamente, convertir 0 en una cadena no tendría los mismos resultados.

    – Andrew Hare

    20 de enero de 2009 a las 19:21

  • Esto es incorrecto: ” se convertirá en 0, no booleano false

    – Cristóbal

    20 de enero de 2009 a las 19:24

  • No, no estoy seguro. Sospecharía que es un tipo numérico, o un lanzamiento booleano.

    – davethegr8

    20 de enero de 2009 a las 19:25

  • No creo que esta explicación sea precisa. Tanto 0 como ” no se convierten en falso antes de la comparación. Ver la respuesta de RoBorg [stackoverflow.com/questions/462663/…

    – Grant Wagner

    Jan 20, 2009 at 19:26

  • check my answer – I looked it up, and the standard says the string will be converted to number!

    – Christoph

    Jan 20, 2009 at 19:27

user avatar
Michael Deardeuff

In many languages, the empty string can be coerced to false.

Beware of doing comparisons with == instead of ===:

alert('' == '0'); //false  
alert(0 == ''); // true  
alert(0 =='0'); // true

== is not transitive.

  • +1 Very nice – do you know how the engine decides which datatype to convert to? Obviously converting 0 to a string would not have the same results.

    – Andrew Hare

    Jan 20, 2009 at 19:21

  • This is wrong – ” will be converted to 0, not boolean false

    – Christoph

    Jan 20, 2009 at 19:24

  • No, I’m not sure. I would suspect that it’s a numerical type, or a boolean cast.

    – davethegr8

    Jan 20, 2009 at 19:25

  • I don’t think this explanation is accurate. Both 0 and ” are not converted to false before the comparison. See RoBorg’s answer [stackoverflow.com/questions/462663/…

    – Grant Wagner

    Jan 20, 2009 at 19:26

  • check my answer – I looked it up, and the standard says the string will be converted to number!

    – Christoph

    Jan 20, 2009 at 19:27

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad