Free

Comparaciones JavaScript

Activar audio

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”.

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 < 1true.

Pero atención:

console.log(null == 0); // false
  • Aquí no hay conversión a número. Solo undefined == null es true.

Caso: undefined < 1

  • undefined se convierte a NaN en contextos numéricos.
  • Y cualquier comparación con NaN siempre da false.
console.log(undefined < 1); // false
console.log(undefined > 1); // false
console.log(undefined == 0); // false

Reglas clave

  • null → 0 en comparaciones numéricas.
  • undefinedNaN en comparaciones numéricas.
  • Comparar con NaN siempre da false.
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).
    • false0
    • Resultado: 0 == 0true

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;
}

Juan Andrés Núñez

Juan Andrés Núñez

Ingeniero Frontend Senior. Especialista en Vue.js. Speaker. Docente profesional. Estoico.