Características de Operadores
Si bien conocemos el comportamiento de los operadores aritméticos, de asignación y de comparación, existen otros operadores que nos permiten realizar operaciones más complejas.
JavaScript cuenta con una gran cantidad de operadores y mecanismos que nos permiten simplificar la escritura de código y realizar operaciones más avanzadas. En este apartado, veremos algunos detalles sobre el uso y funcionamiento de estas características.
Cortocircuito
El intéprete de JavaScript evalúa las expresiones lógicas de izquierda a derecha, lo cual permite que se detenga la evaluación de la expresión si el resultado ya es conocido.
Este comportamiento se conoce como evaluación de cortocircuito (short-circuit evaluation), y es muy útil para simplificar la escritura de código y evitar errores.
La expresión lógica AND (&&
) es un operador de cortocircuito en el cual todos los operandos son convertidos a valores booleanos. Si el resultado de una conversión es false
, el operador AND detiene la evaluación y devuelve el valor original que causó la conversión a false
.
1<expresión falsa> && <expresión>
La <expresión>
nunca es evaluada porque el primer operando es false
. Si la <expresión>
es una función, esta nunca es invocada.
La expresión lógica OR (||
) es un operador de cortocircuito en el cual todos los operandos son convertidos a valores booleanos. Si el resultado de una conversión es true
, el operador OR detiene la evaluación y devuelve el valor original que causó la conversión a true
.
1<expresión verdadera> || <expresión>
La <expresión>
nunca es evaluada porque el primer operando es true
. Si la <expresión>
es una función, esta nunca es invocada.
El operador (??
) es un operador de cortocircuito conocido como fusión nula (nullish coalescing). Este operador devuelve el valor del operando derecho si el operando izquierdo es null
o undefined
, de lo contrario, devuelve el valor del operando izquierdo.
1<expresión izquierda> ?? <expresión derecha>
Este operador puede interpretarse como un caso particular del operador OR (||
), el cual devuelve el valor del operando derecho si el operando izquierdo es un valor falso, como ''
o 0
. En este caso, el operador ??
esta condicionado a null
o undefined
.
1let or_operation = "" || "valor verdadero"; // 'valor verdadero'2console.log(or_operation);3
4let nullish_operation = null ?? "valor verdadero"; // 'valor verdadero'5console.log(nullish_operation);6
7nullish_operation = undefined ?? "valor verdadero"; // 'valor verdadero'8console.log(nullish_operation);
Evidentemente, si ninguno de los operandos es null
o undefined
, el operador ??
devuelve el valor del operando izquierdo.
1let nullish_operation = "operando izquierdo" ?? "operando derecho"; // 'operando izquierdo'2console.log(nullish_operation);
Operador ternario
El operador ternario (?:
) es un operador condicional que permite evaluar una expresión y devolver un valor en función de si la expresión es verdadera o falsa.
La sintaxis del operador ternario es la siguiente:
1<expresión> ? <valor si verdadero> : <valor si falso>
Este operador abstrae el flujo de control de una sentencia if-else
en una sola línea, lo cual permite simplificar la escritura de código.
1let valor = 10;2
3let mensaje =4 valor > 05 ? "El valor es positivo"6 : "El valor es negativo o cero";7console.log(mensaje);
La estructura if-else
equivalente al operador ternario del ejemplo anterior sería la siguiente:
1let valor = 10;2
3let mensaje;4if (valor > 0) {5 mensaje = "El valor es positivo";6} else {7 mensaje = "El valor es negativo o cero";8}9console.log(mensaje);
Por supuesto, el operador ternario puede ser anidado para evaluar múltiples condiciones.
La sintaxis del operador ternario anidado es la siguiente:
1<expresión> ? <valor si verdadero> : <expresión> ? <valor si verdadero> : <valor si falso>
Este operador permite evaluar múltiples condiciones en una sola línea, lo cual puede simplificar la escritura de código.
1let valor = 10;2
3let mensaje =4 valor > 05 ? "El valor es positivo"6 : valor < 07 ? "El valor es negativo"8 : "El valor es cero";9console.log(mensaje);
La estructura if-else
equivalente al operador ternario anidado del ejemplo anterior sería la siguiente:
1let valor = 10;2
3let mensaje;4if (valor > 0) {5 mensaje = "El valor es positivo";6} else if (valor < 0) {7 mensaje = "El valor es negativo";8} else {9 mensaje = "El valor es cero";10}11console.log(mensaje);
Operador de propagación
La sintaxis extendida (spread syntax) es un mecansimo que permite a un elemento iterable, como un arreglo o un objeto, ser expandido en lugares donde cero o más argumentos (para llamadas de función) o elementos (para arreglos literales) son esperados. Para esto se emplea el operador de propagación (...
) como prefijo del elemento iterable.
1let arreglo = [1, 2, 3];2
3let nuevo_arreglo = [0, ...arreglo, 4, 5];4console.log(nuevo_arreglo); // [0, 1, 2, 3, 4, 5]
En este caso, el operador de propagación ...
permite expandir los elementos del arreglo arreglo
en el nuevo arreglo nuevo_arreglo
.
1let objeto = { a: 1, b: 2 };2
3let nuevo_objeto = { ...objeto, c: 3, d: 4 };4console.log(nuevo_objeto); // { a: 1, b: 2, c: 3, d: 4 }
En este caso, el operador de propagación ...
permite expandir las propiedades del objeto objeto
en el nuevo objeto nuevo_objeto
.
1let arreglo = ["Python", "Java", "C++", "JavaScript"];2
3function mostrar(...lenguajes) {4 for (let i = 0; i < lenguajes.length; i++) {5 console.log("Lenguaje:", lenguajes[i]);6 }7}8
9mostrar(...arreglo);
En este caso, el operador de propagación ...
permite expandir los elementos del arreglo arreglo
en los argumentos de la función mostrar
.
También es posible utilizar el operador de propagación en la asignación de arreglos, donde podremos desestructurar el arreglo en variables individuales.
1let arreglo = ["Python", "Java", "C++", "JavaScript"];2
3let [primer_elemento, ...resto_elementos] = arreglo;4console.log(primer_elemento); // 'Python'5console.log(resto_elementos); // ['Java', 'C++']