Conocemos muchos operadores de comparación de las matemáticas.
En JavaScript se escriben así:
- Mayor/menor que:
a > b
,a < b
. - Mayor/menor que o igual:
a >= b
,a <= b
. - Iguala:
a == b
, ten en cuenta que el doble signo de igualdad==
significa la prueba de igualdad, mientras que uno soloa = b
significa una asignación. - No son iguales. En matemáticas la notación es
≠
, pero en JavaScript se escribe comoa != b
.
En este artículo aprenderemos más sobre los diferentes tipos de comparaciones, cómo las hace JavaScript, incluyendo peculiaridades importantes.
Al final encontrarás una buena receta para evitar problemas relacionados con las «peculiaridades de JavaScript».
Boolean es el resultado
Todos los operadores de comparación devuelven un valor booleano:
-
true
– significa «sí», «correcto» o «la verdad». -
false
– significa «no», «incorrecto» o «no la verdad».
Por ejemplo:
alert( 2 > 1 ); // true (correct)alert( 2 == 1 ); // false (wrong)alert( 2 != 1 ); // true (correct)
El resultado de una comparación puede asignarse a una variable, como cualquier valor:
let result = 5 > 4; // assign the result of the comparisonalert( result ); // true
Comparación de cadenas
Para ver si una cadena es mayor que otra, JavaScript utiliza el llamado orden «diccionario» o «lexicográfico».
En otras palabras, las cadenas se comparan letra a letra.
Por ejemplo:
alert( 'Z' > 'A' ); // truealert( 'Glow' > 'Glee' ); // truealert( 'Bee' > 'Be' ); // true
El algoritmo para comparar dos cadenas es sencillo:
- Compara el primer carácter de ambas cadenas.
- Si el primer carácter de la primera cadena es mayor (o menor) que el de la otra, entonces la primera cadena es mayor (o menor) que la segunda. Hemos terminado.
- De lo contrario, si los primeros caracteres de ambas cadenas son iguales, compara los segundos caracteres de la misma manera.
- Repite hasta el final de cualquiera de las cadenas.
- Si ambas cadenas terminan con la misma longitud, entonces son iguales. De lo contrario, la cadena más larga es mayor.
En el primer ejemplo anterior, la comparación 'Z' > 'A'
llega a un resultado en el primer paso.
La segunda comparación 'Glow'
y 'Glee'
necesita más pasos ya que las cadenas se comparan carácter por carácter:
-
G
es igual aG
. -
l
es igual al
. -
o
es mayor quee
. Deténgase aquí. La primera cadena es mayor.
El algoritmo de comparación dado anteriormente es aproximadamente equivalente al utilizado en los diccionarios o guías telefónicas, pero no es exactamente el mismo.
Por ejemplo, las mayúsculas y minúsculas importan. Una letra mayúscula "A"
no es igual a la minúscula "a"
. ¿Cuál es mayor? La minúscula "a"
. ¿Por qué? Porque el carácter minúsculo tiene un índice mayor en la tabla de codificación interna que utiliza JavaScript (Unicode). Volveremos a los detalles y consecuencias específicas de esto en el capítulo Cadenas.
Comparación de diferentes tipos
Cuando se comparan valores de diferentes tipos, JavaScript convierte los valores en números.
Por ejemplo:
alert( '2' > 1 ); // true, string '2' becomes a number 2alert( '01' == 1 ); // true, string '01' becomes a number 1
Para valores booleanos, true
se convierte en 1
y false
en 0
.
Por ejemplo:
alert( true == 1 ); // truealert( false == 0 ); // true
Es posible que al mismo tiempo:
- Dos valores sean iguales.
- Uno de ellos es
true
como booleano y el otro esfalse
como booleano.
Por ejemplo:
let a = 0;alert( Boolean(a) ); // falselet b = "0";alert( Boolean(b) ); // truealert(a == b); // true!
Desde el punto de vista de JavaScript, este resultado es bastante normal. Una comprobación de igualdad convierte los valores utilizando la conversión numérica (de ahí que "0"
se convierta en 0
), mientras que la conversión explícita Boolean
utiliza otro conjunto de reglas.
Igualdad estricta
Una comprobación de igualdad regular ==
tiene un problema. No puede diferenciar 0
de false
:
alert( 0 == false ); // true
Lo mismo ocurre con una cadena vacía:
alert( '' == false ); // true
Esto ocurre porque los operandos de distinto tipo se convierten en números mediante el operador de igualdad ==
. Una cadena vacía, al igual que false
, se convierte en un cero.
¿Qué hacer si queremos diferenciar 0
de false
?
Un operador de igualdad estricto ===
comprueba la igualdad sin conversión de tipos.
En otras palabras, si a
y b
son de tipos diferentes, entonces a === b
devuelve inmediatamente false
sin un intento de conversión.
Probemos:
alert( 0 === false ); // false, because the types are different
También existe un operador de «no igualdad estricta» !==
análogo a !=
.
El operador de igualdad estricta es un poco más largo de escribir, pero hace que sea obvio lo que está pasando y deja menos espacio para los errores.
Comparación con null y undefined
Hay un comportamiento no intuitivo cuando null
o undefined
se comparan con otros valores.
Para una comprobación de igualdad estricta===
Estos valores son diferentes, porque cada uno de ellos es un tipo diferente.
alert( null === undefined ); // false
Para una comprobación no estricta==
Hay una regla especial. Estos dos son una «dulce pareja»: son iguales entre sí (en el sentido de ==
), pero no cualquier otro valor.
alert( null == undefined ); // true
Para las matemáticas y otras comparaciones< > <= >=
null/undefined
se convierten en números: null
se convierte en 0
, mientras que undefined
se convierte en NaN
.
Ahora veamos algunas cosas curiosas que ocurren cuando aplicamos estas reglas. Y, lo que es más importante, cómo no caer en una trampa con ellas.
Extraño resultado: nulo frente a 0
Comparemos null
con un cero:
alert( null > 0 ); // (1) falsealert( null == 0 ); // (2) falsealert( null >= 0 ); // (3) true
Matemáticamente, es extraño. El último resultado afirma que «null
es mayor o igual que cero», por lo que en una de las comparaciones anteriores debe ser true
, pero ambas son falsas.
La razón es que una comprobación de igualdad ==
y las comparaciones > < >= <=
funcionan de forma diferente. Las comparaciones convierten null
en un número, tratándolo como 0
. Por eso (3) null >= 0
es verdadera y (1) null > 0
es falsa.
Por otro lado, la comprobación de igualdad ==
para undefined
y null
está definida de forma que, sin ninguna conversión, son iguales entre sí y no son iguales a nada más. Por eso (2) null == 0
es falso.
Un indefinido incomparable
El valor undefined
no debería compararse con otros valores:
alert( undefined > 0 ); // false (1)alert( undefined < 0 ); // false (2)alert( undefined == 0 ); // false (3)
¿Por qué le disgusta tanto el cero? Siempre es falso!
Obtenemos estos resultados porque:
- Las comparaciones
(1)
y(2)
devuelvenfalse
porqueundefined
se convierte enNaN
yNaN
es un valor numérico especial que devuelvefalse
para todas las comparaciones. - La comprobación de igualdad
(3)
devuelvefalse
porqueundefined
sólo es igual anull
,undefined
, y a ningún otro valor.
Evitar problemas
¿Por qué hemos repasado estos ejemplos? ¿Debemos recordar siempre estas peculiaridades? Pues la verdad es que no. En realidad, estas cosas complicadas se irán haciendo familiares con el tiempo, pero hay una forma sólida de evitar problemas con ellas:
- Trate cualquier comparación con
undefined/null
excepto la igualdad estricta===
con un cuidado excepcional. - No utilice comparaciones
>= > < <=
con una variable que pueda sernull/undefined
, a menos que esté realmente seguro de lo que está haciendo. Si una variable puede tener estos valores, compruébalos por separado.
Resumen
- Los operadores de comparación devuelven un valor booleano.
- Las cadenas se comparan letra a letra en el orden del «diccionario».
- Cuando se comparan valores de diferentes tipos, se convierten en números (con la exclusión de una comprobación de igualdad estricta).
- Los valores
null
yundefined
son iguales a==
entre sí y no son iguales a ningún otro valor. - Tenga cuidado al utilizar comparaciones como
>
o<
con variables que pueden ser ocasionalmentenull/undefined
. Comprobarnull/undefined
por separado es una buena idea.