Precedencia de operadores
=========================

La **precedencia de operadores** determina el orden en el cual los operadores son evaluados uno respecto del otro. Los operadores con mayor precedencia se convierten en los operandos de los operadores con menor precedencia.

Pruébalo
--------

Precedencia y Asociatividad
---------------------------

Considere la expresión descrita debajo. Note que `OP1` y `OP2` son ambos ejemplos de operadores.


```js
a OP1 b OP2 c
```


 Si `OP1` y `OP2` tienen diferente niveles de precedencia (véase la tabla debajo), el operador
 con la precedencia más alta va primero y la asociatividad no importa. Observe como la multiplicación
 tiene mayor precedencia que la suma y se ejecuta primero, a pesar de que la suma se escribe primero en el código.


```js
console.log(3 + 10 \* 2); // muestra 23
console.log(3 + (10 \* 2)); // muestra 23 porque los paréntesis son superfluos
console.log((3 + 10) \* 2); // muestra 26 porque los paréntesis cambian el orden
```


 La asociatividad a la izquierda (de izquierda a derecha) significa que es procesado como
 `(a OP1 b) OP2 c`, mientras que la asociatividad a la derecha (de derecha a izquierda) significa que es interpretado como
 `a OP1 (b OP2 c)`. Los opearadores de asignación son de asociatividad a la derecha, entonces se puede escribir:


```js
a = b = 5; // es igual a escribir a = (b = 5);
```


 con el resultado esperado de que `a` y `b` obtienen el valor 5. Esto
 es porque el operador de asignación retorna el valor que es asignado. Primero,
 `b` es establecido en 5. Luego `a` también es establecida en 5, el valor de retorno
 de `b = 5`, también conocido como el operando de la derecha de la asignación.

 Como otro ejemplo, el operador de exponenciación tiene la particularidad de tener asociatividad a la derecha,
 a diferencia de los restantes operadores aritméticos que poseen asociatividad a la izquierda. Es interesante notar que,
 el order de evaluación siempre es de izquierda a derecha sin importar la asociatividad y la precedencia.


|  |  |
| --- | --- |
| Código | Salida |
| 
```js
function echo(nombre, num) {
    console.log("Evaluando el lado " + nombre);
    return num;
}
// Nótese el operador división (/)
console.log(echo("izquierdo", 6) / echo("derecho", 2));
```

 | 
```
Evaluando el lado izquierdo
Evaluando el lado derecho
3
```

 |
| 
```js
function echo(nombre, num) {
    console.log("Evaluando el lado " + nombre);
    return num;
}
// Nótese el operador potencia (\*\*)
console.log(echo("izquierdo", 2) \*\* echo("derecho", 3));
```
 | 
```
Evaluando el lado izquierdo
Evaluando el lado derecho
8
```
 |

 La diferencia en asociatividad entra en juego cuando hay múltiples operadores con la
 misma precedencia. Con un único operador u operadores con diferente precedencia,
 la asociatividad no afecta la salida, como puede verse en el ejemplo de arriba. En el ejemplo
 debajo, observe como la asociatividad afecta la salida cuando múltiples operadores idénticos
 son usados.


|  |  |
| --- | --- |
| Código | Saludo |
| 
```js
function echo(nombre, num) {
    console.log("Evaluando el lado " + nombre);
    return num;
}
// Nótese el operador división (/)
console.log(echo("izquierdo", 6) / echo("medio", 2) / echo("derecho", 3));
```

 | 
```
Evaluando el lado izquierdo
Evaluando el lado medio
Evaluando el lado derecho
1
```

 |
| 
```js
function echo(nombre, num) {
    console.log("Evaluando el lado " + nombre);
    return num;
}
// Nótese el operador potencia (\*\*)
console.log(echo("izquierdo", 2) \*\* echo("medio", 3) \*\* echo("derecho", 2));
```

 | 
```
Evaluando el lado izquierdo
Evaluando el lado medio
Evaluando el lado derecho
512
```

 |
| 
```js
function echo(nombre, num) {
    console.log("Evaluando el lado " + nombre);
    return num;
}
// Nótese los paréntesis alrededor de las potencias de la izquierda y el medio
console.log((echo("izquierdo", 2) \*\* echo("medio", 3)) \*\* echo("derecho", 2));
```
 | 
```
Evaluando el lado izquierdo
Evaluando el lado medio
Evaluando el lado derecho
64
```
 |

 Viendo los fragmentos de códigos de arriba, `6 / 2 / 3` es lo mismo que
 `(6 / 2) / 3` porque la división es asociativa a la izquierda. La potencia, por otro lado,
 es asociativa a la derecha, entonces `2 ** 3 ** 2` es lo mismo que
 `2 ** (3 ** 2)`. Por lo tanto, hacer `(2 ** 3) ** 2` cambia el orden
 y el resultado en el 64 que se ve en la tabla de arriba.

 Recuerde que la precedencia viene antes de la asociatividad. Entonces, mezclando
 división y potencia, esta última precede a la división. Por ejemplo,
 `2 ** 3 / 3 ** 2` resulta en 0.8888888888888888 porque es lo mismo que hacer
 `(2 ** 3) / (3 ** 2)`.

### Nota sobre agrupamiento y operadores de cortocircuito

 En la tabla debajo, **Agrupamiento** se lista con la mayor precedencia.
 Sin embargo, esto no siempre significa que la expresión dentro de los símbolos
 de agrupación `( … )` es evaluada primero, especialmente cuando se trata de
 cortocircuitos.

 Cortocircuitar es una jerga para la evaluación condicional. Por ejemplo, en la expresión
 `a && (b + c)`, si `a` es falsy (en-US), entonces
 la expresión `(b + c)` no será evaluada, incluso si está dentro de
 paréntesis. Se podría decir que el operador de conjunción lógica ("&&") está
 "cortocircuitado". Junto con la conjunción lógica, otros operadores cortocircuitados
 son la disyunción lógica ("||"), la coalescencia nula ("??"), el encadenamiento opcional ("?."),
 y el operador condicional ternario. A continuación, algunos ejemplos.


```js
a || (b \* c); // evalúa primero `a`, luego produce `a` si `a` es "truthy"
a && (b < c); // evalúa primero `a`, luego produce `a` si `a` es "falsy"
a ?? (b || c); // evalúa primero `a`, luego produce `a` si `a` no es `null` ni `undefined`
a?.b.c; // evalúa primero `a`, luego produce `undefined` si `a` es `null` ó `undefined`
```

Ejemplos
--------


```js
3 > 2 && 2 > 1;
// Retorna `true`

3 > 2 > 1;
// Retorna `false` porque 3 > 2 es `true`, luego `true` es convertido a 1
// por coerción de tipos, luego `true` > 1 se convierte en 1 > 1, que es
// `false`. Agregar paréntesis hace que las cosas se vean claras: (3 > 2) > 1.
```

Tabla
-----

La siguiente tabla lista los operadores en orden de mayor precedencia (19) a menor precedencia (1).

 Nótese que la sintaxis spread está intencionalmente excluída de la tabla — porque, citando
 una respuesta en Stack Overflow, "la sintaxis spread no es un operador y por lo tanto no tiene una precedencia. Es parte de la sintaxis de arreglos literales y llamadas a funciones (y objetos literales)."


| Precedencia | Tipo de operador | Asociatividad | Operadores individuales |
| --- | --- | --- | --- |
| 19 | Agrupamiento | n/a | `( … )` |
| 18 | Acceso a propiedades (notación por punto) | a la izquierda | `… . …` |
| Acceso a propiedades (notación por corchetes) | a la izquierda | `… [ … ]` |
| `new` (con lista de argumentos) | n/a | `new … ( … )` |
| Llamada a función | a la izquierda | `… ( … )` |
| Encadenamiento opcional | a la izquierda | `?.` |
| 17 | `new` (sin lista de argumentos) | a la derecha | `new …` |
| 16 | Incremento sufijo | n/a | `… ++` |
| Decremento sufijo | `… --` |
| 15 | NOT lógico (!) (en-US) | a la derecha | `! …` |
| NOT a nivel de bits (~) (en-US) | `~ …` |
| Suma unaria (+) (en-US) | `+ …` |
| Negación unaria (-) (en-US) | `- …` |
| Incremento prefijo | `++ …` |
| Decremento prefijo | `-- …` |
| `typeof` | `typeof …` |
| `void` | `void …` |
| `delete` | `delete …` |
| `await` | `await …` |
| 14 | Potenciación (\*\*) (en-US) | a la derecha | `… ** …` |
| 13 | Multiplicación (\*) (en-US) | a la izquierda | `… * …` |
| División (/) | `… / …` |
| Resto (%) | `… % …` |
| 12 | Adición (+) | a la izquierda | `… + …` |
| Sustracción (-) | `… - …` |
| 11 | Desplazamiento de bits a la izquierda (<<) (en-US) | a la izquierda | `… << …` |
| Desplazamiento de bits a la derecha (>>) (en-US) | `… >> …` |
| Desplazamiento de bits a la derecha sin signo (>>>) (en-US) | `… >>> …` |
| 10 | Menor a (<) (en-US) | a la izquierda | `… < …` |
| Menor o igual a (<=) (en-US) | `… <= …` |
| Mayor a (>) (en-US) | `… > …` |
| Mayor o igual a (>=) (en-US) | `… >= …` |
| `in` | `… in …` |
| `instanceof` | `… instanceof …` |
| 9 | Igualdad (==) | a la izquierda | `… == …` |
| Desigualdad (!=) (en-US) | `… != …` |
| Igualdad estricta (===) | `… === …` |
| Desigualdad estricta (!==) (en-US) | `… !== …` |
| 8 | AND a nivel de bits (&) (en-US) | a la izquierda | `… & …` |
| 7 | XOR a nivel de bits (^) (en-US) | a la izquierda | `… ^ …` |
| 6 | OR a nivel de bits (|) (en-US) | a la izquierda | `… | …` |
| 5 | AND lógico (&&) | a la izquierda | `… && …` |
| 4 | OR lógico (||) | a la izquierda | `… || …` |
| Operador de coalescencia nula (??) (en-US) | a la izquierda | `… ?? …` |
| 3 | Operador condicional (ternario) | a la derecha | `… ? … : …` |
| 2 | Asignación | a la derecha | `… = …` |
| `… += …` |
| `… -= …` |
| `… **= …` |
| `… *= …` |
| `… /= …` |
| `… %= …` |
| `… <<= …` |
| `… >>= …` |
| `… >>>= …` |
| `… &= …` |
| `… ^= …` |
| `… |= …` |
| `… &&= …` |
| `… ||= …` |
| `… ??= …` |
| `yield` | a la derecha | `yield …` |
| `yield*` | `yield* …` |
| 1 | Operador coma | a la izquierda | `… , …` |