Ir al contenido principal

Operadores lógicos

Introducción

Los operadores lógicos son componentes fundamentales en la programación que nos permiten combinar y manipular valores booleanos para crear condiciones más complejas. En JavaScript, estos operadores no solo trabajan con valores estrictamente booleanos, sino que incorporan características particulares que los hacen muy versátiles para múltiples situaciones de programación.

En este artículo exploraremos en detalle cada uno de los operadores lógicos disponibles en JavaScript, sus peculiaridades, el concepto de evaluación de cortocircuito y cómo podemos aprovechar estas propiedades para escribir código más eficiente y expresivo. Dominar estos operadores te permitirá crear condiciones precisas y manejar la lógica de tu aplicación de manera elegante.

AND lógico (&&)

El operador AND lógico, representado por el símbolo &&, evalúa si dos expresiones son verdaderas. Este operador devuelve true únicamente cuando ambas expresiones son verdaderas; en cualquier otro caso, devuelve false.

Tabla de verdad del operador &&

true && true     // true
true && false    // false
false && true    // false
false && false   // false

Uso básico en condiciones

let edad = 25;
let tieneLicencia = true;

if (edad >= 18 && tieneLicencia) {
    console.log("Puede conducir legalmente");
} else {
    console.log("No puede conducir legalmente");
}

En este ejemplo, solo si ambas condiciones son verdaderas (la persona es mayor de edad Y tiene licencia), el mensaje "Puede conducir legalmente" se mostrará en la consola.

OR lógico (||)

El operador OR lógico, representado por el símbolo ||, evalúa si al menos una de dos expresiones es verdadera. Este operador devuelve true cuando cualquiera de las expresiones (o ambas) son verdaderas; devuelve false únicamente cuando ambas expresiones son falsas.

Tabla de verdad del operador ||

true || true     // true
true || false    // true
false || true    // true
false || false   // false

Uso básico en condiciones

let esFeriado = false;
let esFinDeSemana = true;

if (esFeriado || esFinDeSemana) {
    console.log("No hay que trabajar hoy");
} else {
    console.log("Es día laborable");
}

En este ejemplo, si cualquiera de las condiciones es verdadera (es feriado O es fin de semana), el mensaje "No hay que trabajar hoy" se mostrará en la consola.

NOT lógico (!)

El operador NOT lógico, representado por el símbolo !, invierte el valor booleano de una expresión. Si la expresión es verdadera, ! la convierte en falsa, y viceversa.

Tabla de verdad del operador !

!true   // false
!false  // true

Uso básico en condiciones

let esUsuarioLogueado = false;

if (!esUsuarioLogueado) {
    console.log("Por favor, inicia sesión para continuar");
}

// Equivalente a:
if (esUsuarioLogueado === false) {
    console.log("Por favor, inicia sesión para continuar");
}

El operador NOT es útil para simplificar condiciones, especialmente cuando queremos verificar si algo NO es verdadero.

Doble negación (!!)

Un patrón común es usar el operador NOT dos veces (!!) para convertir cualquier valor a su equivalente booleano:

console.log(!!0);         // false
console.log(!!"");        // false
console.log(!!null);      // false
console.log(!!undefined); // false
console.log(!!NaN);       // false

console.log(!!1);         // true
console.log(!!"hola");    // true
console.log(!!{});        // true
console.log(!![]));       // true

Esto es equivalente a usar Boolean():

console.log(Boolean("hola")); // true
console.log(Boolean(0));      // false

Evaluación de cortocircuito

Una característica importante de los operadores && y || en JavaScript es la evaluación de cortocircuito (short-circuit evaluation). Esto significa que estos operadores no siempre evalúan ambas expresiones.

Cortocircuito con &&

El operador && deja de evaluar tan pronto como encuentra una expresión falsa, ya que el resultado final será falso independientemente de las expresiones posteriores:

false && expresionQueNoSeEvalua  // false, la segunda expresión no se evalúa

Cortocircuito con ||

El operador || deja de evaluar tan pronto como encuentra una expresión verdadera, ya que el resultado final será verdadero independientemente de las expresiones posteriores:

true || expresionQueNoSeEvalua  // true, la segunda expresión no se evalúa

Aplicaciones prácticas del cortocircuito

Este comportamiento se puede aprovechar para crear patrones útiles en JavaScript:

1. Valores por defecto con ||
function saludar(nombre) {
    // Si nombre es falsy (undefined, null, ""), usa "Invitado"
    nombre = nombre || "Invitado";
    console.log("Hola, " + nombre);
}

saludar("Ana");    // "Hola, Ana"
saludar("");       // "Hola, Invitado"
saludar();         // "Hola, Invitado"
2. Ejecución condicional con &&
let usuarioLogueado = true;

// La función solo se ejecuta si usuarioLogueado es true
usuarioLogueado && mostrarPanelDeUsuario();

// Equivalente a:
if (usuarioLogueado) {
    mostrarPanelDeUsuario();
}

Operador nullish coalescing (??)

El operador nullish coalescing (fusión de nulos), introducido en ES2020, está representado por ??. Es similar al operador ||, pero con una diferencia clave: solo considera null y undefined como valores falsos, no otros valores "falsy" como 0, "" o false.

const valor1 = null ?? "valor por defecto";
console.log(valor1);  // "valor por defecto"

const valor2 = undefined ?? "valor por defecto";
console.log(valor2);  // "valor por defecto"

const valor3 = 0 ?? "valor por defecto";
console.log(valor3);  // 0 (a diferencia de ||, que devolvería "valor por defecto")

const valor4 = "" ?? "valor por defecto";
console.log(valor4);  // "" (a diferencia de ||, que devolvería "valor por defecto")

const valor5 = false ?? "valor por defecto";
console.log(valor5);  // false (a diferencia de ||, que devolvería "valor por defecto")

Este operador es especialmente útil cuando queremos usar un valor alternativo solo cuando la variable es null o undefined, pero queremos mantener otros valores falsy como 0 o "" si son valores válidos.

Comparación entre || y ??

// Con el operador ||
function mostrarCantidad(cantidad) {
    // 0 se considera falsy, así que se usará el valor por defecto
    const cantidadFinal = cantidad || 10;
    console.log(cantidadFinal);
}

mostrarCantidad(0);  // 10 (no es lo que queremos si 0 es un valor válido)

// Con el operador ??
function mostrarCantidadMejor(cantidad) {
    // Solo null y undefined activarán el valor por defecto
    const cantidadFinal = cantidad ?? 10;
    console.log(cantidadFinal);
}

mostrarCantidadMejor(0);  // 0 (mantiene el valor original)

Encadenamiento de operaciones lógicas

Podemos combinar múltiples operadores lógicos para crear expresiones complejas:

let edad = 25;
let tieneIdentificacion = true;
let esMayorDeEdad = edad >= 18;
let puedeEntrar = esMayorDeEdad && tieneIdentificacion;
let descuentoEspecial = (edad < 18 || edad >= 65) && tieneIdentificacion;

if (esMayorDeEdad && tieneIdentificacion || esClienteVip) {
    console.log("Bienvenido al club");
}

Precedencia de operadores lógicos

La precedencia de los operadores lógicos es la siguiente (de mayor a menor):

  1. NOT (!)
  2. AND (&&)
  3. OR (||)

Esto significa que ! se evalúa primero, luego && y finalmente ||:

// Ejemplo de precedencia
const resultado = true || false && false;
// Se evalúa como: true || (false && false)
// true || false
// true

Para evitar confusiones, es recomendable usar paréntesis para clarificar el orden de evaluación:

const resultado = true || (false && false);  // Más claro

Patrones comunes de uso

1. Validación de múltiples condiciones

function puedeObtenerLicencia(edad, pasoPruebaTeorica, pasoPruebaPractica) {
    return edad >= 18 && pasoPruebaTeorica && pasoPruebaPractica;
}

2. Comprobación de rango

function estaEnRango(valor, min, max) {
    return valor >= min && valor <= max;
}

console.log(estaEnRango(25, 18, 65));  // true

3. Verificación de propiedades de objetos anidados

// Evitar errores al acceder a propiedades que podrían no existir
function obtenerCiudad(usuario) {
    return usuario && usuario.direccion && usuario.direccion.ciudad;
}

// En ES2020+, podríamos usar el operador de encadenamiento opcional
function obtenerCiudadModerno(usuario) {
    return usuario?.direccion?.ciudad;
}

4. Asignación condicional

// Asignar un valor solo si la condición es verdadera
let mensaje = '';
let esAdmin = true;

esAdmin && (mensaje = "Bienvenido, administrador");
console.log(mensaje);  // "Bienvenido, administrador"

Conversión implícita a boolean

En JavaScript, cuando los operadores lógicos (&&, ||, !) operan con valores no booleanos, estos valores se convierten implícitamente a booleanos para la evaluación, pero el resultado puede ser el valor original, no necesariamente true o false.

Valores considerados falsy (se convierten a false):

  • false
  • 0, -0, 0n (BigInt cero)
  • "" (string vacío)
  • null
  • undefined
  • NaN

Valores considerados truthy (se convierten a true):

  • Cualquier otro valor diferente a los anteriores
  • "0", "false" (son strings no vacíos, por lo tanto truthy)
  • {} (objeto vacío)
  • [] (array vacío)

Ejemplos de conversión implícita:

// Con el operador &&
console.log("Hola" && "Mundo");  // "Mundo" (último valor evaluado)
console.log("Hola" && "");       // "" (se detiene en el primer falsy)
console.log(0 && "Cualquier cosa"); // 0 (se detiene en el primer falsy)

// Con el operador ||
console.log("Hola" || "Mundo");  // "Hola" (primer valor truthy)
console.log("" || "Alternativa"); // "Alternativa" (primer truthy)
console.log(0 || 42);            // 42 (primer truthy)

// Combinando operadores
console.log("" || "Alternativa" && "Resultado"); // "Resultado"
// Se evalúa como: ("" || "Alternativa") && "Resultado"
// "Alternativa" && "Resultado"
// "Resultado"

Esta característica de JavaScript es la que permite los patrones de cortocircuito que vimos anteriormente.

Resumen

Los operadores lógicos en JavaScript son herramientas versátiles que van más allá de simples operaciones booleanas. El operador && (AND) requiere que todas las condiciones sean verdaderas, el operador || (OR) requiere que al menos una condición sea verdadera, y el operador ! (NOT) invierte el valor booleano de una expresión.

La evaluación de cortocircuito de && y || permite patrones elegantes como valores por defecto y ejecución condicional de código. El operador nullish coalescing (??) ofrece una alternativa más precisa a || cuando solo queremos considerar null y undefined como valores a reemplazar.

Dominar estos operadores y sus características especiales te permitirá escribir código más conciso, expresivo y eficiente en tus aplicaciones JavaScript.

En el próximo artículo, profundizaremos en la precedencia de operadores, un concepto crucial para entender cómo JavaScript evalúa expresiones complejas que combinan múltiples tipos de operadores.