Comparaciones JavaScript
Las comparaciones en JavaScript parecen simples… hasta que no. Este fundamental destapa una de las zonas más traicioneras del lenguaje: la coerción de tipos, la diferencia entre == y ===, y el verdadero significado de “igualdad”.
- Igualdad débil (==) y desigualdad débil (!=)
- Igualdad estricta (===) y desigualdad estricta (!==)
- Comparaciones con null y undefined
- Comparaciones con NaN
- Comparaciones con 0, false, '' (valores falsy)
- Comparaciones con Object.is()
- Comparaciones relacionales (<, >, etc.)
- Comparación de referencia vs valor
- Comparación de strings
- Comparar objetos
- truthy y falsy en comparaciones
- Enlaces útiles
Las comparaciones en JavaScript son más traicioneras de lo que parecen. Aunque a menudo se enseñan como simples operadores, en realidad abren la puerta a uno de los temas más confusos del lenguaje: la coerción de tipos y las referencias.
Este fundamental expande lo que vimos brevemente en el módulo de operadores.
Igualdad débil (==
) y desigualdad débil (!=
)
Realizan coerción de tipo antes de comparar. Esto significa que convierten los operandos para que "encajen" antes de decidir si son iguales.
console.log(5 == '5'); // true
console.log(null == undefined); // true
console.log(false == 0); // true
console.log('' == 0); // true
Esta coerción sigue una tabla interna compleja que no es intuitiva.
Por eso se dice que ==
puede parecer que funciona, hasta que no.
Igualdad estricta (===
) y desigualdad estricta (!==
)
Comparan sin convertir tipos: tipo y valor deben ser exactamente iguales.
console.log(5 === '5'); // false
console.log(null === undefined); // false
console.log(false === 0); // false
Pero cuidado: con objetos, arrays y funciones, incluso ===
compara referencias, no contenido.
console.log([] === []); // false
console.log({} === {}); // false
let a = [1, 2];
let b = a;
console.log(a === b); // true
¿Por qué [] === []
da false
?
Porque cada array es un objeto distinto en memoria. Aunque su contenido sea igual, no son el mismo objeto. En JavaScript, recuerda: los objetos se comparan por referencia, no por valor.
Comparaciones con null
y undefined
console.log(null == undefined); // true
console.log(null === undefined); // false
==
los considera iguales porque ambos representan "ausencia de valor".===
los considera distintos porque sus tipos son distintos (null
es un objeto*,undefined
es... undefined).
Este caso causa errores cuando esperas detectar "valor no definido" y usas ==
sin entender lo que incluye.
Comparaciones con NaN
NaN
(Not a Number) no es igual a sí mismo.
console.log(NaN === NaN); // false
console.log(Number.isNaN(NaN)); // true
Esto rompe la intuición: ningún otro valor en JS se comporta así. Si estás comparando cosas que podrían contener NaN
, usa el método Number.isNaN()
.
Comparaciones con 0
, false
, ''
(valores falsy
)
console.log(0 == false); // true
console.log('' == false); // true
console.log('' == 0); // true
Esto vuelve especialmente peligrosas las comparaciones con ==
.
En un formulario, por ejemplo, input == false
puede atrapar más cosas de las que esperas.
Comparaciones con Object.is()
Object.is()
es como ===
pero con algunas diferencias sutiles:
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(0, -0)); // false
console.log(0 === -0); // true
- Detecta
NaN
como igual a sí mismo. - Distingue entre
0
y-0
.
En casos extremos o en validaciones críticas, Object.is()
es más preciso.
Comparaciones relacionales (<
, >
, etc.)
Cuando haces comparaciones como <
, >
, <=
, >=
, JavaScript convierte los valores a número (si no son strings comparables).
Esto puede dar resultados muy raros:
console.log(null < 1); // true
console.log(undefined < 1); // false
Caso: null < 1
- En comparaciones relacionales,
null
se convierte a 0. - Así que:
0 < 1
→true
.
Pero atención:
console.log(null == 0); // false
- Aquí no hay conversión a número. Solo
undefined == null
estrue
.
Caso: undefined < 1
undefined
se convierte a NaN en contextos numéricos.- Y cualquier comparación con
NaN
siempre dafalse
.
console.log(undefined < 1); // false
console.log(undefined > 1); // false
console.log(undefined == 0); // false
Reglas clave
null
→ 0 en comparaciones numéricas.undefined
→NaN
en comparaciones numéricas.- Comparar con
NaN
siempre dafalse
.
console.log(null < 1); // true
console.log(null >= 0); // true
console.log(undefined < 1); // false
console.log(undefined == null); // true
Comparación de referencia vs valor
- Los primitivos (
number
,string
,boolean
,null
,undefined
,symbol
,bigint
) se comparan por valor. - Los objetos (
arrays
,function
,object
) se comparan por referencia.
let a = { name: 'Juan' };
let b = { name: 'Juan' };
console.log(a === b); // false
Aunque el contenido sea igual, los objetos están en espacios distintos de memoria.
Comparación de strings
Si comparas dos strings, se compara carácter a carácter según su orden Unicode:
console.log('apple' < 'banana'); // true
console.log('2' < '10'); // false → because '2' comes after '1' in Unicode
Evita comparar strings numéricos con <
, >
.
Comparar objetos
Cuando comparas objetos con ==
o ===
, estás comparando referencias, no contenido:
let a = { age: 30 };
let b = { age: 30 };
let c = a;
console.log(a === b); // false → distintos objetos
console.log(a === c); // true → misma referencia
truthy
y falsy
en comparaciones
Recuerda que en contextos booleanos, ciertos valores son considerados falsy
:
false
,0
,''
,null
,undefined
,NaN
.
Todo lo demás es truthy
.
Esto puede producir comparaciones engañosas:
console.log([] == false); // true (!)
console.log('' == 0); // true (!)
console.log([] == ![]); // true (!)
[]
es un array vacío → en coerción a boolean, se considera true.false
ya es un boolean.- Pero como es ==, JavaScript convierte ambos operandos a número:
[]
→''
→0
(array vacío → string vacío → número 0).false
→0
- Resultado:
0 == 0
→true
Enlaces útiles
Desafío Práctico: Comparaciones en JavaScript
Prueba a resolver este desafío antes de continuar
Las comparaciones en JavaScript pueden ser más complicadas de lo que parecen. La diferencia principal está entre:
==
(comparación débil): Convierte tipos antes de comparar.===
(comparación estricta): Compara tipo y valor exactamente.
En aplicaciones reales, especialmente en formularios, esta diferencia es crucial:
// Form validation examples
let userAge = "18"; // String from input field
let requiredAge = 18; // Number from our code
console.log(userAge == requiredAge); // true (converts string to number)
console.log(userAge === requiredAge); // false (different types)
Tu tarea es crear funciones de validación que manejen correctamente los datos que llegan de formularios web, donde todo viene como strings, y algunos campos pueden estar vacíos.
Tu Código
Solución
Validación de Edad
Para validar edad desde un formulario, necesitamos convertir el string a número y verificar que la conversión funcionó. Number("18")
nos da 18
, pero Number("abc")
nos da NaN
.
Comparación de Contraseñas
Las contraseñas deben ser exactamente iguales, sin conversión de tipos. ===
es esencial aquí porque "0" == 0
es true
, pero no queremos que eso pase con contraseñas.
Campos Vacíos
En formularios, null
, undefined
y ""
representan campos vacíos. Pero 0
y false
son valores válidos que un usuario podría ingresar.
Comparación de Arrays
Los arrays se comparan por referencia, no por contenido. [] === []
es false
porque son objetos diferentes en memoria, aunque estén vacíos.
Código Final
function isValidAge(input) {
const age = Number(input);
if (isNaN(age)) {
return false;
}
return age >= 18;
}
function arePasswordsMatching(password1, password2) {
return password1 === password2;
}
function isEmptyField(value) {
return value === null || value === undefined || value === "";
}
function hasSameContent(array1, array2) {
// For this basic version, just check if both are empty
return array1.length === 0 && array2.length === 0;
}