# short-circuiting

[JS](../../..) ⟩ [statement](../../statement) ⟩ [expression](../../statement/expr) ⟩ [operator](..) ⟩ [term]() ⟩ short-circuiting

{% hint style="success" %}
```javascript
a && b               // b may not be evaluated
a ?? b               // (same)
condition ? a : b    // only one of a and b is evaluated
obj ?. prop          // prop may not be evaluated
f ?. (args)          // args expressions may not be evaluated
```

:star2: [table-of-operators](../table-of-operators "mention")
{% endhint %}

{% tabs %}
{% tab title="🔴 主題" %}
* [logical](../logical "mention") (&&, ||) - a && b, a || b
* [nullish-coalescing](../logical/nullish-coalescing "mention") - a ?? b
* [conditional-operator](../ternary/conditional-operator "mention") - condition ? a : b
* [optional-chaining](../../../val/obj/prop/access/optional-chaining "mention") - obj ?. prop, obj ?. \[prop]
* [optional-invocation-.](../../../val/obj/prop/access/optional-invocation-. "mention") - f ?. (args)
{% endtab %}

{% tab title="💈範例" %}
replit：[short-circuiting (optional invocation)](https://replit.com/@pegasusroe/short-circuiting-fargs#index.js)

```javascript
let f = null;      // ⭐ not a function
let x = 0;

try { 
    // 1. `x++` evaluated first. ⭐ 
    // 2. TypeError: f is not a function ⛔ 
    f(x++);     
} catch(e) { 
    log(e.name, e.message);
    log(x);        // 1 (x is incremented)
} 

// ⭐ short-circuiting (`x++` not evaluated)
f ?. (x++),        // undefined (no error)
x,                 // 1 (x not incremented)
```
{% endtab %}

{% tab title="📘 手冊" %}
* [Operator precedence](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) ⟩ [short-circuiting](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#short-circuiting)&#x20;
{% endtab %}

{% tab title="📗 參考" %}
* [ ] [javascript-the-definitive-guide](../../../../master/ref/javascript-the-definitive-guide "mention") ⟩ 4.5.1 Conditional Invocation
{% endtab %}
{% endtabs %}
