Los operadores son la forma en la que las expresiones hacen el trabajo
Casi cualquier línea de JavaScript que haga algo interesante está construida con operadores: símbolos que toman uno o dos valores y devuelven otro. El + suma, === compara, && combina booleanos y ? : elige entre dos valores. La mayoría te sonarán de otros lenguajes, pero hay unos cuantos con peculiaridades propias de JavaScript que conviene tener claras desde el principio.
Vamos a recorrerlos por categorías, dejando para el final los que usarás menos pero que resultan clave cuando los necesitas.
Operadores aritméticos en JavaScript
Los básicos se comportan como esperarías:
Algunos detalles que conviene tener en cuenta:
/siempre hace división en punto flotante.7 / 2da3.5, no3. Si necesitas un entero, usaMath.floor(7 / 2)oMath.trunc(7 / 2).%es el resto, no el módulo matemático puro. Conserva el signo del operando de la izquierda:-7 % 3da-1, no2.+está sobrecargado. Si cualquiera de los dos lados es una cadena, concatena en lugar de sumar:"3" + 1da"31". Ahora vemos más sobre esto.
Incremento y decremento
La diferencia entre count++ y ++count solo importa cuando usas el valor de la expresión en esa misma línea. Como sentencia independiente, hacen exactamente lo mismo. La mayoría de guías de estilo recomiendan count += 1 porque se lee mejor.
El operador + tiene doble personalidad
Este detalle nos ha pillado a todos alguna vez:
Si alguno de los dos operandos es un string, + pasa a ser concatenación y fuerza al otro lado a convertirse en string. El resto de operadores aritméticos hace justo lo contrario: convierten los strings a números:
Lo que te llevas a casa: cuando arma cadenas, usa template literals (`price: ${5}`). Cuando hagas cálculos, asegúrate de que las entradas sean realmente números — con Number(x) o parseInt(x, 10) haces la conversión explícita.
Operadores de comparación en JavaScript
Las comparaciones devuelven booleanos. Hay dos variantes: estricta y laxa.
=== y !== son estrictos: comparan mismo valor y mismo tipo. En cambio, == y != hacen coerción de tipos antes de comparar, lo que genera sorpresas como que null == undefined dé true o que [] == false también dé true. Por eso, la recomendación es usar === y !== por defecto. La única excepción habitual es x == null, un atajo muy cómodo para preguntar "¿x es null o undefined?".
Los operadores de orden se comportan como esperarías con números, y de forma alfabética con cadenas:
La comparación de strings se hace en base a los códigos de carácter, así que distingue entre mayúsculas y minúsculas. Si lo que buscas es un orden más natural para personas, tira de String.prototype.localeCompare.
Operadores lógicos en JavaScript
&& (AND), || (OR) y ! (NOT) sirven para combinar booleanos, pero dan bastante más juego del que esperarías de un álgebra puramente booleana.
El detalle curioso: && y || no devuelven true ni false. Lo que devuelven es uno de sus operandos. && retorna el primer valor falsy, o el último si todos son truthy. || retorna el primer valor truthy, o el último si todos son falsy.
Por eso es común ver patrones como const displayName = user.name || "Guest": coge el primer valor que no esté vacío. Es una forma concisa de escribirlo, pero ojo con un detalle: || considera que 0, "" y false también activan el valor por defecto. Si esos son valores válidos en tu caso, mejor usa ?? (lo vemos más abajo).
Ambos operadores hacen cortocircuito: si el lado antes del operador ya determina el resultado, el lado siguiente ni siquiera se ejecuta.
El operador de coalescencia nula ??
El operador ?? funciona parecido a ||, pero solo salta cuando el valor es null o undefined. No se activa con 0, "" ni false.
Usa ?? cuando un valor válido pueda ser falsy (por ejemplo, contadores, cadenas vacías o un false explícito). Usa || cuando cualquier valor falsy deba interpretarse como "ausente". En código moderno, ?? suele ser la opción más segura para valores opcionales con defaults que no son null ni undefined.
Operadores de asignación en JavaScript
= asigna un valor. Las formas compuestas combinan la asignación con otra operación:
También tenemos los operadores de asignación lógica — ||=, &&= y ??= —, que asignan un valor solo si el actual cumple cierta condición:
Son muy útiles para asignar valores por defecto sin tener que escribir un if larguísimo.
El operador ternario en JavaScript
condition ? a : b es la versión en forma de expresión del clásico if/else. Devuelve a cuando la condición es verdadera (truthy) y b en caso contrario:
El operador ternario brilla cuando tienes que elegir entre dos valores cortos. El problema llega al anidarlos: si acabas escribiendo algo como a ? b : c ? d : e, mejor tira de if/else o de un objeto de búsqueda.
typeof e instanceof
typeof devuelve un string que describe el tipo del operando:
Dos trampas que conviene grabarse a fuego: typeof null devuelve "object" (un bug de 1995 que ya quedó para siempre), y los arrays también dan "object". Usa Array.isArray(x) para detectar arrays y x === null para saber si algo es null.
instanceof, por su parte, comprueba si un objeto fue creado a partir de un constructor concreto:
Spread y rest: el mismo ..., dos usos distintos
Vas a ver ... en dos contextos diferentes. Como spread, expande un iterable en elementos individuales:
Como rest, agrupa varios valores en un único array, algo muy habitual al desestructurar o al definir parámetros de funciones:
Misma sintaxis, tareas opuestas. Spread desempaqueta; rest agrupa. Cuál es cuál lo decide el contexto: en una llamada o en un literal, desempaqueta; en una lista de parámetros o en un patrón de destructuring, recoge.
Precedencia de operadores (ante la duda, pon paréntesis)
Los operadores tienen una precedencia que determina cuál se ejecuta primero cuando los combinas. La multiplicación le gana a la suma, la comparación le gana a los lógicos, y así sucesivamente:
La tabla completa es larga y nadie se la aprende de memoria. Con un hábito sencillo cubres el 99% de los casos: cuando mezcles operadores y no tengas total certeza del orden, pon paréntesis. El código se lee mejor y no depende de la memoria de quien lo lea.
Operadores a nivel de bits (casi nunca es lo que buscas)
Para que quede completo: &, |, ^, ~, <<, >> y >>> trabajan sobre la representación binaria de los enteros. Los verás en código de gráficos, en protocolos de bajo nivel y en alguna que otra API que usa máscaras de bits como flags.
Un truco bastante común, aunque discutible: n | 0 trunca un número a un entero de 32 bits, y antes se abusaba de esto como un Math.trunc más rápido. No lo hagas: Math.trunc se lee mejor y funciona con números fuera del rango de 32 bits.
Lo que sigue: if/else
Los operadores producen valores; if/else usa esos valores para decidir qué rama de código ejecutar. La mayor parte de lo que harás con los operadores de comparación y los operadores lógicos que vimos antes será pasar sus resultados a condicionales, y justo de eso trata la siguiente página.
Preguntas frecuentes
¿Cuáles son los operadores principales en JavaScript?
JavaScript tiene operadores aritméticos (+, -, *, /, %, **), de comparación (===, !==, <, >), lógicos (&&, ||, !), de asignación (=, +=, -=) y algunos especiales como el ternario ? :, typeof y la coalescencia nula ??. Son los ladrillos con los que construyes expresiones y controlas el flujo del programa.
¿Qué diferencia hay entre == y === en JavaScript?
=== comprueba que coincidan tanto el valor como el tipo. == convierte los tipos antes de comparar, así que 0 == "0" da true pero 0 === "0" da false. Usa === por defecto: las reglas de conversión de == son lo bastante raras como para colarte bugs que no verás ni en la revisión de código.
¿Para qué sirve el operador ternario en JavaScript?
condición ? a : b es un if/else de una sola línea que devuelve un valor. Si condición es truthy, la expresión vale a; si no, b. Es práctico para cosas cortas como const label = count === 1 ? 'item' : 'items', pero en cuanto anidas ternarios el código se vuelve ilegible enseguida.
¿Cuándo conviene usar ?? en vez de ||?
|| hace fallback con cualquier valor falsy, incluidos 0, "" y false. ?? solo hace fallback con null o undefined. Si quieres que count ?? 10 respete un 0 válido, usa ??. Si de verdad quieres que cualquier falsy dispare el valor por defecto, entonces sí, ||.