Módulo 03: Operadores

Objetivos del módulo

  • Entender qué es un operador, un operando y una expresión
  • Usar los operadores aritméticos, incluidos la potencia ** y el resto %
  • Dominar la asignación compuesta y el incremento/decremento (prefijo frente a sufijo)
  • Comparar valores correctamente: == frente a ===, y Object.is
  • Usar &&, || y ! sabiendo que cortocircuitan y que devuelven operandos
  • Distinguir ?? de || y usar el encadenamiento opcional ?.
  • Aplicar la asignación lógica &&=, ||= y ??=
  • Escribir condiciones compactas con el operador ternario
  • Conocer typeof, instanceof, in, spread ..., el operador coma y los operadores de bits
  • Saber en qué orden se evalúan los operadores (precedencia) y seguir buenas prácticas

1. Operadores, operandos y expresiones

📘 Concepto: Un operador es un símbolo que realiza una operación sobre uno o varios valores, llamados operandos. Una expresión es cualquier trozo de código que produce un valor. En precio * 2, el operador es *, los operandos son precio y 2, y toda la expresión produce un número.

Según cuántos operandos necesitan:

Tipo Operandos Ejemplos
Unario Uno -x, !activo, typeof x, contador++
Binario Dos a + b, edad >= 18, nombre ?? 'anónimo'
Ternario Tres condicion ? siSi : siNo
const precio = 20;
const total = precio * 2 + 5; // una expresión con dos operadores
console.log(total); // 45

2. Operadores aritméticos

Operador Operación Ejemplo Resultado
+ Suma 7 + 2 9
- Resta 7 - 2 5
* Multiplicación 7 * 2 14
/ División 7 / 2 3.5
% Resto de la división 7 % 2 1
** Potencia (ES2016) 2 ** 10 1024
-x Negación (cambio de signo) -(5) -5
+x Conversión a número +'5' 5
console.log(7 / 2);   // 3.5  (la división NO es entera)
console.log(10 / 3);  // 3.3333333333333335
console.log(2 ** 0.5); // 1.4142135623730951 (raíz cuadrada de 2)

2.1 El operador resto %

% devuelve lo que sobra de una división entera. Es mucho más útil de lo que parece:

console.log(17 % 5);  // 2   (17 = 5 × 3 + 2)
console.log(10 % 2);  // 0   → 10 es par
console.log(7 % 2);   // 1   → 7 es impar
console.log(7.5 % 2); // 1.5 (también funciona con decimales)

// Usos típicos
const numero = 42;
const esPar = numero % 2 === 0;     // ¿es par?
const segundosTotales = 135;
const minutos = Math.floor(segundosTotales / 60); // 2
const segundos = segundosTotales % 60;            // 15
console.log(`${minutos} min ${segundos} s`);      // 2 min 15 s

⚠️ Importante: En JavaScript % es el resto, no el módulo matemático: el resultado lleva el signo del dividendo. -7 % 2 da -1, no 1. Por eso, para saber si un número es impar, compara con !== 0 en vez de con === 1: -7 % 2 === 1 es false.

2.2 División entera

No hay un operador de división entera, pero puedes combinar / con Math:

console.log(Math.floor(7 / 2));  // 3  (redondea hacia abajo)
console.log(Math.trunc(7 / 2));  // 3  (quita los decimales)
console.log(Math.floor(-7 / 2)); // -4 ← con negativos son distintos
console.log(Math.trunc(-7 / 2)); // -3

2.3 La potencia ** y sus paréntesis

console.log(2 ** 3 ** 2);   // 512  ← se agrupa por la DERECHA: 2 ** (3 ** 2) = 2 ** 9
console.log((-3) ** 2);     // 9
console.log(-(3 ** 2));     // -9
// console.log(-3 ** 2);    ❌ SyntaxError: Unary operator used immediately before exponentiation expression...

📘 Concepto: JavaScript obliga a usar paréntesis en -3 ** 2 porque en matemáticas es ambiguo (¿(-3)² o -(3²)?). Es un ejemplo de diseño que prefiere un error claro a un resultado sorprendente.

2.4 El + con textos

Como viste en el módulo 02, si uno de los operandos de + es un texto, concatena:

console.log('3' + 4 + 5); // '345'
console.log(3 + 4 + '5'); // '75'  (primero 3 + 4 = 7, luego '7' + '5')
console.log('8' - '3');   // 5     (el - siempre convierte a número)

3. Asignación y operadores compuestos

El operador = asigna. Los operadores compuestos combinan una operación con la asignación:

Operador Equivale a Ejemplo (si x vale 10) x pasa a valer
x += 5 x = x + 5 x += 5 15
x -= 3 x = x - 3 x -= 3 7
x *= 2 x = x * 2 x *= 2 20
x /= 4 x = x / 4 x /= 4 2.5
x %= 3 x = x % 3 x %= 3 1
x **= 2 x = x ** 2 x **= 2 100
let saldo = 100;
saldo -= 30;   // pagamos 30
saldo += 50;   // ingresamos 50
saldo *= 1.02; // 2 % de interés
console.log(saldo); // 122.4

let frase = 'Hola';
frase += ' mundo'; // también funciona con textos
console.log(frase); // Hola mundo

📘 Concepto: La asignación es en sí misma una expresión que devuelve el valor asignado. Por eso es posible escribir a = b = 0 (se evalúa de derecha a izquierda: primero b = 0, que devuelve 0, y luego a = 0). Úsalo con moderación: puede dificultar la lectura.


4. Incremento y decremento

++ suma 1 y -- resta 1 a una variable. Pueden ir antes (prefijo) o después (sufijo) de la variable, y la diferencia importa cuando usas el resultado en la misma expresión:

Forma Nombre Qué hace Qué devuelve
x++ Sufijo (posincremento) Suma 1 a x El valor anterior
++x Prefijo (preincremento) Suma 1 a x El valor nuevo
x-- Sufijo Resta 1 a x El valor anterior
--x Prefijo Resta 1 a x El valor nuevo
let a = 5;
const b = a++; // b recibe 5 (el valor ANTES de incrementar); después a pasa a 6
console.log(a, b); // 6 5

let c = 5;
const d = ++c; // c pasa a 6 y d recibe 6 (el valor DESPUÉS de incrementar)
console.log(c, d); // 6 6

💡 Consejo: Para evitar confusiones, usa ++ y -- solos en su propia línea (o en el for), donde prefijo y sufijo dan igual. Expresiones como n++ + ++n son correctas pero ilegibles. Muchos equipos prefieren directamente contador += 1.

// ✅ Claro
let intentos = 0;
intentos++;

// ❌ Confuso
let n = 0;
const r = n++ + ++n; // ¿cuánto vale r? (respuesta: 2) Nadie debería tener que pensarlo

5. Operadores de comparación

Los operadores de comparación siempre devuelven un booleano (true o false).

5.1 Relacionales: <, >, <=, >=

console.log(10 > 5);   // true
console.log(10 <= 10); // true
console.log(3 >= 7);   // false

Con textos, se compara carácter a carácter según su código Unicode (orden “de diccionario” informático):

console.log('a' < 'b');     // true
console.log('abc' < 'abd'); // true
console.log('Z' < 'a');     // true  ← las mayúsculas van antes que las minúsculas
console.log('á' < 'b');     // false ← las letras con tilde tienen códigos mayores
console.log('10' < '9');    // true  ← ¡comparación de textos! '1' < '9'
console.log('10' < 9);      // false (uno es número: convierte '10' a 10)

⚠️ Importante: Si comparas números que te llegan como texto (de un formulario, de prompt…), conviértelos antes con Number(): '10' < '9' es true. Y para ordenar palabras en español correctamente (tildes, eñe), usarás localeCompare en el módulo 08.

5.2 Igualdad: == frente a ===

Operador Nombre Qué hace
=== Igualdad estricta true si son del mismo tipo y tienen el mismo valor. No convierte nada
!== Desigualdad estricta Lo contrario de ===
== Igualdad débil (abstracta) Si los tipos son distintos, convierte antes de comparar
!= Desigualdad débil Lo contrario de ==
console.log(1 === 1);    // true
console.log(1 === '1');  // false (number frente a string)
console.log(1 == '1');   // true  (convierte '1' a 1)

El problema es que las reglas de conversión de == producen resultados difíciles de prever:

Comparación == ===
1 == '1' true false
0 == '' true false
0 == '0' true false
'' == '0' false (¡pero los dos son == 0!) false
false == '0' true false
false == 'false' false false
null == undefined true false
null == 0 false false
' \t\n' == 0 true (espacios en blanco → 0) false
[1, 2] == '1,2' true false
[] == ![] true (¡un valor igual a su negación!) false
NaN == NaN false false

⚠️ Importante: Usa siempre === y !==. Así comparas exactamente lo que ves. La única excepción que algunos equipos admiten es valor == null, que es true tanto para null como para undefined; aun así, hoy es más claro usar ?? (sección 7) o valor === null || valor === undefined.

5.3 Comparar objetos: por referencia

Dos objetos solo son iguales si son el mismo objeto, no si tienen el mismo contenido:

console.log({} === {});         // false: dos objetos distintos
console.log([1] === [1]);       // false

const a = { x: 1 };
const b = a;
console.log(a === b);           // true: misma referencia

5.4 Object.is: la igualdad más estricta

Object.is(a, b) es casi igual que ===, pero corrige dos casos raros:

Comparación === Object.is
NaN con NaN false true
-0 con +0 true false
'a' con 'a' true true
console.log(NaN === NaN);         // false
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(-0, 0));    // false

En el día a día usarás ===. Object.is aparece en casos muy concretos (por ejemplo, comprobar si un valor ha cambiado en bibliotecas como React).

5.5 Comparaciones encadenadas: una trampa

console.log(1 < 2 < 3); // true  (por casualidad)
console.log(3 > 2 > 1); // false ← ¿?
// Se evalúa de izquierda a derecha: (3 > 2) es true, y true > 1 → 1 > 1 → false

// ✅ Lo correcto
const x = 2;
console.log(1 < x && x < 3); // true

6. Operadores lógicos: &&, || y !

6.1 Lo básico

Operador Nombre Resultado (con booleanos)
a && b Y lógico (AND) true solo si ambos son true
a \|\| b O lógico (OR) true si al menos uno es true
!a NO lógico (NOT) Invierte: true → false y viceversa
const edad = 25;
const tieneEntrada = true;

console.log(edad >= 18 && tieneEntrada); // true: mayor de edad Y con entrada
console.log(edad < 12 || edad > 65);     // false: ni niño ni jubilado
console.log(!tieneEntrada);              // false

Tablas de verdad:

a b a && b a \|\| b !a
true true true true false
true false false true false
false true false true true
false false false false true

6.2 Evaluación en cortocircuito

📘 Concepto: && y || evalúan de izquierda a derecha y se detienen en cuanto conocen el resultado. Es la evaluación en cortocircuito:

  • En a && b, si a es falsy, el resultado ya es “falso” y b ni se evalúa.
  • En a || b, si a es truthy, el resultado ya es “verdadero” y b ni se evalúa.
const usuario = null;

// Sin cortocircuito, usuario.nombre daría error. Como usuario es null,
// la parte derecha nunca se ejecuta:
console.log(usuario && usuario.nombre); // null (sin error)

6.3 Devuelven un operando, no un booleano

Esto sorprende a quien viene de otros lenguajes: && y || no devuelven true o false, sino uno de los dos operandos:

Expresión Devuelve
a && b a si a es falsy; si no, b
a \|\| b a si a es truthy; si no, b
console.log(true && 'hola');    // 'hola'
console.log(0 && 'hola');       // 0
console.log('Ana' || 'defecto'); // 'Ana'
console.log('' || 'defecto');   // 'defecto'
console.log(null || 0 || 'x');  // 'x' (el primer truthy, o el último si no hay ninguno)

Esto da lugar a dos patrones muy usados:

// Patrón 1: valor por defecto con ||
const nombreIntroducido = '';
const nombre = nombreIntroducido || 'Invitado';
console.log(nombre); // Invitado

// Patrón 2: ejecutar algo solo si se cumple una condición con &&
const esAdmin = true;
esAdmin && console.log('Mostrando panel de administración');

💡 Consejo: El patrón 2 es habitual en código compacto (y en JSX de React), pero en código normal un if (esAdmin) { ... } es más legible. Úsalo con criterio.

6.4 El NO ! y la doble negación

! sí devuelve siempre un booleano. !! lo aplica dos veces y convierte cualquier valor en su booleano equivalente:

console.log(!'');       // true  ('' es falsy)
console.log(!'texto');  // false
console.log(!!null);    // false
console.log(!!'hola');  // true

7. Nullish coalescing: ??

El problema del patrón || para valores por defecto es que trata como “vacío” cualquier valor falsy, incluidos 0, '' y false, que a menudo son valores válidos:

const volumenGuardado = 0; // el usuario ha silenciado el sonido a propósito

const volumen = volumenGuardado || 50;
console.log(volumen); // 50 ❌ ¡hemos ignorado su elección!

El operador ?? (nullish coalescing, ES2020) solo usa el valor de la derecha si el de la izquierda es null o undefined (los valores nullish):

const volumenGuardado = 0;
const volumen = volumenGuardado ?? 50;
console.log(volumen); // 0 ✅
Expresión \|\| ??
0 ?? 10 / 0 \|\| 10 10 0
'' ?? 'x' / '' \|\| 'x' 'x' ''
false ?? true / false \|\| true true false
NaN ?? 1 / NaN \|\| 1 1 NaN
null ?? 'x' / null \|\| 'x' 'x' 'x'
undefined ?? 'x' / undefined \|\| 'x' 'x' 'x'

💡 Consejo: Pregúntate: “¿0, '' o false son valores válidos aquí?”. Si la respuesta es sí (cantidades, textos opcionales, interruptores), usa ??. Si quieres sustituir cualquier valor “vacío”, usa ||. En código moderno, ?? es casi siempre lo que buscas.

⚠️ Importante: No puedes mezclar ?? con && o || sin paréntesis: a || b ?? c es un SyntaxError. Escribe (a || b) ?? c para dejar clara tu intención.


8. Encadenamiento opcional: ?.

Acceder a una propiedad de null o undefined es uno de los errores más frecuentes en JavaScript:

const usuario = { nombre: 'Ana', direccion: { ciudad: 'Madrid' } };

console.log(usuario.trabajo.empresa);
// ❌ TypeError: Cannot read properties of undefined (reading 'empresa')

El operador ?. (optional chaining, ES2020) comprueba si lo que hay a su izquierda es null o undefined. Si lo es, se detiene y devuelve undefined en lugar de lanzar un error:

const usuario = {
  nombre: 'Ana',
  direccion: { ciudad: 'Madrid' },
  etiquetas: ['admin'],
  saludar() {
    return 'Hola';
  },
};

// 1. Propiedades
console.log(usuario.direccion?.ciudad); // Madrid
console.log(usuario.trabajo?.empresa);  // undefined (sin error)

// 2. Índices de arrays (y propiedades con corchetes)
console.log(usuario.etiquetas?.[0]);    // admin
console.log(usuario.amigos?.[0]);       // undefined

// 3. Llamadas a funciones que quizá no existan
console.log(usuario.saludar?.());       // Hola
console.log(usuario.despedir?.());      // undefined (no intenta llamar)

// Cortocircuito: si falla al principio, no evalúa el resto de la cadena
const vacio = null;
console.log(vacio?.a.b.c);              // undefined
Forma Significa
obj?.prop obj.prop, o undefined si obj es nullish
obj?.[clave] obj[clave], o undefined si obj es nullish
fn?.() Llama a fn(), o devuelve undefined si fn es nullish

Combinado con ?? es especialmente potente:

const ciudad = usuario.trabajo?.direccion?.ciudad ?? 'Ciudad desconocida';
console.log(ciudad); // Ciudad desconocida

⚠️ Importante: No abuses de ?.. Si una propiedad debería existir siempre, es mejor que el programa falle con un error claro a que oculte el problema con un undefined silencioso. Úsalo solo para lo que de verdad es opcional (datos de una API que pueden faltar, configuración opcional…). Además, ?. no se puede usar a la izquierda de una asignación: usuario?.nombre = 'Luis' es un error de sintaxis.


9. Asignación lógica: &&=, ||= y ??=

ES2021 combinó los operadores lógicos con la asignación. Solo asignan si se cumple la condición correspondiente:

Operador Equivale a Asigna cuando x es…
x \|\|= y x \|\| (x = y) falsy
x &&= y x && (x = y) truthy
x ??= y x ?? (x = y) null o undefined
const config = { tema: '', volumen: 0, idioma: null };

config.tema ||= 'claro';  // '' es falsy → asigna
config.volumen ??= 50;    // 0 no es nullish → NO asigna
config.idioma ??= 'es';   // null es nullish → asigna

console.log(config); // { tema: 'claro', volumen: 0, idioma: 'es' }

const sesion = { usuario: 'ana' };
sesion.usuario &&= sesion.usuario.toUpperCase(); // solo si hay usuario
console.log(sesion); // { usuario: 'ANA' }

💡 Consejo: ??= es ideal para valores por defecto de opciones: “si no me has dicho nada, uso esto”. Fíjate en que, a diferencia de x = x ?? y, si x ya tiene valor no se realiza ninguna asignación.


10. El operador ternario ? :

Es el único operador con tres operandos. Elige entre dos valores según una condición:

condición ? valorSiVerdadero : valorSiFalso
const edad = 20;
const tipo = edad >= 18 ? 'mayor de edad' : 'menor de edad';
console.log(tipo); // mayor de edad

const stock = 0;
console.log(`Producto ${stock > 0 ? 'disponible' : 'agotado'}`); // Producto agotado

const unidades = 1;
console.log(`${unidades} ${unidades === 1 ? 'unidad' : 'unidades'}`); // 1 unidad

💡 Consejo: El ternario es perfecto para elegir un valor (dentro de una plantilla, al inicializar una const). Para ejecutar acciones distintas, o si necesitas anidar varios ternarios, usa if/else (módulo 04): a ? b : c ? d : e es difícil de leer.


11. Otros operadores

11.1 typeof

Ya lo conoces del módulo 02: devuelve el tipo de un valor como texto.

console.log(typeof 42);        // number
console.log(typeof 'hola');    // string
console.log(typeof undefined); // undefined

11.2 instanceof (adelanto)

Comprueba si un objeto fue creado a partir de una clase o constructor concreto. Lo entenderás del todo en el módulo 09:

console.log([] instanceof Array);         // true
console.log(new Date() instanceof Date);  // true
console.log([] instanceof Object);        // true (los arrays también son objetos)

11.3 in (adelanto)

Comprueba si una propiedad existe en un objeto:

const usuario = { nombre: 'Ana' };
console.log('nombre' in usuario); // true
console.log('edad' in usuario);   // false
console.log(0 in ['x']);          // true (el índice 0 existe)

11.4 Spread ... (adelanto)

Los tres puntos “esparcen” los elementos de un array, una cadena o las propiedades de un objeto. Lo verás a fondo en los módulos 06 y 07:

const numeros = [3, 7, 1];
console.log(Math.max(...numeros));     // 7 (equivale a Math.max(3, 7, 1))
console.log([...numeros, 10]);         // [ 3, 7, 1, 10 ]
console.log([...'hola']);              // [ 'h', 'o', 'l', 'a' ]

const direccion = { ciudad: 'Madrid' };
console.log({ ...direccion, cp: 28001 }); // { ciudad: 'Madrid', cp: 28001 }

11.5 El operador coma (mención)

Evalúa varias expresiones de izquierda a derecha y devuelve la última. Casi solo se ve en bucles for con dos variables o en código minificado:

const k = (1, 2, 3);
console.log(k); // 3

for (let i = 0, j = 10; i < j; i++, j--) {
  // i sube y j baja a la vez
}

⚠️ Importante: No uses el operador coma en tu código salvo en el for. Su presencia suele indicar un error: por ejemplo, Math.max(1, 2) no es el operador coma (son argumentos), pero const x = (a, b) sí lo es, y probablemente no es lo que querías.


12. Operadores de bits (breve)

Trabajan con los números a nivel de bits (ceros y unos), convirtiéndolos temporalmente a enteros de 32 bits. Son poco frecuentes en aplicaciones web, pero aparecen en gráficos, criptografía, compresión o permisos.

Operador Nombre Ejemplo Resultado
& AND de bits 5 & 3 (101 & 011) 1 (001)
\| OR de bits 5 \| 3 7 (111)
^ XOR de bits 5 ^ 3 6 (110)
~ NOT de bits ~5 -6
<< Desplazamiento a la izquierda 5 << 1 10
>> Desplazamiento a la derecha 5 >> 1 2
>>> Desplazamiento a la derecha sin signo -5 >>> 28 15
// Ejemplo práctico: permisos combinados como "banderas"
const LEER = 0b001;     // 1
const ESCRIBIR = 0b010; // 2
const BORRAR = 0b100;   // 4

const permisos = LEER | ESCRIBIR;              // 3 (0b011)
console.log((permisos & ESCRIBIR) !== 0);      // true: puede escribir
console.log((permisos & BORRAR) !== 0);        // false: no puede borrar

⚠️ Importante: No confundas & con && ni | con ||. if (a & b) es una operación de bits, no un “y lógico”. Es un error de tecleo frecuente que ESLint puede detectar.


13. Precedencia de operadores

📘 Concepto: La precedencia decide qué operador se aplica primero cuando hay varios en una expresión, igual que en matemáticas la multiplicación va antes que la suma. La asociatividad decide el orden cuando tienen la misma precedencia (de izquierda a derecha o al revés).

console.log(2 + 3 * 4);   // 14 (primero 3 * 4)
console.log((2 + 3) * 4); // 20 (los paréntesis mandan)

Tabla simplificada, de mayor a menor precedencia:

Nivel Operadores Asociatividad
1 ( ... ) agrupación —
2 ., ?., [], llamadas f(), new Izquierda a derecha
3 Sufijos x++, x-- —
4 Unarios: !, -x, +x, ++x, --x, typeof, await Derecha a izquierda
5 ** Derecha a izquierda
6 *, /, % Izquierda a derecha
7 +, - Izquierda a derecha
8 <<, >>, >>> Izquierda a derecha
9 <, <=, >, >=, in, instanceof Izquierda a derecha
10 ==, !=, ===, !== Izquierda a derecha
11 &, después ^, después \| Izquierda a derecha
12 && Izquierda a derecha
13 \|\|, ?? Izquierda a derecha
14 ? :, =, +=, &&=, \|\|=, ??=, =>… Derecha a izquierda
15 , Izquierda a derecha
// Cómo se lee una expresión con varios operadores
const edad = 30;
const tieneCarne = true;
const resultado = edad >= 18 && tieneCarne || edad > 70;
// 1º comparaciones: (edad >= 18) → true, (edad > 70) → false
// 2º &&: true && true → true
// 3º ||: true || false → true
console.log(resultado); // true

💡 Consejo: Nadie se sabe la tabla entera de memoria. Lo profesional es usar paréntesis siempre que la expresión no sea obvia: (edad >= 18 && tieneCarne) || edad > 70 se entiende a la primera.


14. Buenas prácticas y errores comunes

❌ Evita ✅ Prefiere Por qué
if (x == 0) if (x === 0) == convierte tipos ('' == 0 es true)
if (x === NaN) if (Number.isNaN(x)) NaN nunca es igual a nada
const v = cantidad \|\| 1 (si 0 es válido) const v = cantidad ?? 1 \|\| descarta 0, '' y false
a && b && a.b && a.b.c a?.b?.c Más corto y legible
x = x + 1 x += 1 o x++ Más conciso
const r = n++ + ++n Varias líneas simples Ilegible y propenso a errores
if (1 < x < 10) if (1 < x && x < 10) La primera siempre es true
a ? b : c ? d : e if / else if / else Los ternarios anidados se leen mal
'10' < '9' con datos de formulario Number(a) < Number(b) Los textos se comparan carácter a carácter
if (a = 5) if (a === 5) = asigna; es un error clásico de tecleo

⚠️ Importante: if (a = 5) no da error: asigna 5 a a y, como 5 es truthy, siempre entra en el if. Es un fallo muy difícil de ver. ESLint lo detecta con la regla no-cond-assign.


15. Ejercicios

Ejercicio 1: Calculadora de operaciones

Declara dos constantes a = 17 y b = 5 y muestra en una tabla (console.table con un objeto) el resultado de +, -, *, /, %, **, la división entera con Math.trunc y si a es par. Repite con a = -17 y explica por qué cambia el resto.

Ejercicio 2: Conversor de tiempo

Dada una cantidad de segundos (por ejemplo, 98765), calcula cuántos días, horas, minutos y segundos son usando /, Math.floor y %. Muestra el resultado como 1 d 3 h 26 min 5 s.

Ejercicio 3: Predice el resultado

Sin ejecutar, escribe el resultado de cada expresión. Después compruébalo y explica los fallos:

'5' + 3 - 1
'5' - 3 + 1
0 == '0'
0 === '0'
null ?? 'a'
0 || 'b'
0 ?? 'c'
'' && 'd'
'e' && 'f'
!!'0'
3 > 2 > 1
2 ** 3 ** 2

Ejercicio 4: Precio con descuentos

Escribe un programa con las constantes precio, esSocio (booleano), cupon (texto que puede ser '') y unidades. Calcula:

  • Descuento del 10 % si esSocio (usa el ternario).
  • 5 € menos si cupon no está vacío (usa && o el ternario).
  • Envío gratis si el total supera 50 € o el cliente es socio. Muestra un resumen con plantillas de texto y prueba varias combinaciones.

Ejercicio 5: Configuración por defecto

Dado el objeto const preferencias = { tema: null, fuente: 0, notificaciones: false, idioma: '' };, usa ??= y ||= para que, al final, tema sea 'oscuro', fuente siga siendo 0, notificaciones siga siendo false e idioma sea 'es'. Justifica en un comentario qué operador has elegido para cada propiedad.

Ejercicio 6: Datos opcionales de una API

Tienes esta respuesta de una API:

const respuesta = {
  pedido: { id: 1042, cliente: { nombre: 'Luis' }, lineas: [{ producto: 'Ratón', precio: 19.9 }] },
};

Usando ?. y ??, muestra: el nombre del cliente, su email (o 'sin email'), el nombre del primer producto, el precio del segundo producto (o 0) y el resultado de llamar a respuesta.pedido.calcularTotal si existe (o 'no disponible'). Ninguna línea debe lanzar error.

Ejercicio 7: Permisos con bits

Define las banderas LEER = 1, ESCRIBIR = 2, BORRAR = 4 y ADMIN = 8. Crea tres usuarios con distintas combinaciones de permisos usando | y escribe, para cada uno, si puede leer, escribir, borrar o es administrador usando &. ¿Qué número resulta de combinar todos los permisos?


Resumen

Concepto Sintaxis Nota
Aritméticos + - * / % ** % es el resto (signo del dividendo)
Asignación compuesta += -= *= /= %= **= x += 1 equivale a x = x + 1
Incremento x++ / ++x Sufijo devuelve el valor anterior; prefijo, el nuevo
Igualdad estricta ===, !== Úsala siempre
Igualdad débil ==, != Convierte tipos: evítala
Igualdad exacta Object.is(a, b) NaN igual a NaN; -0 distinto de 0
Lógicos &&, \|\|, ! Cortocircuitan y devuelven un operando
Nullish coalescing a ?? b b solo si a es null o undefined
Encadenamiento opcional a?.b, a?.[i], f?.() undefined en vez de error
Asignación lógica \|\|=, &&=, ??= Asignan solo si se cumple la condición
Ternario cond ? a : b Para elegir valores, no para anidar
Tipo y pertenencia typeof, instanceof, in Tipo, clase y existencia de propiedad
Spread ...array, ...objeto Esparce elementos o propiedades
Bits & \| ^ ~ << >> >>> Enteros de 32 bits; no confundir con &&
Precedencia ( ) primero Ante la duda, paréntesis