Recently came across short-circuit evaluation and was a little confused by it as i only got into programming the past week. From what i understand if what ever es before the first double pipe is true then it will stop and not evaluate what es after the double pipe. For Example:
Example 1:
var a = true;
var b = a || {};
So i assume if a exists then assign a to b otherwise b is equal to an object. What i dont understand is where i will use this and how it differs to a ternary operator, isn't the short circuit evaluation the same as:
Example 2:
var a = true;
var b = (a) ? a : {};
Why would one use example 1 over example 2 as it isn't any slower to write out or is there a speed benefit of the use of one over the other? or is this just a silly question and perhaps i'm missing something. If someone could clear this up for me that would be great.
Recently came across short-circuit evaluation and was a little confused by it as i only got into programming the past week. From what i understand if what ever es before the first double pipe is true then it will stop and not evaluate what es after the double pipe. For Example:
Example 1:
var a = true;
var b = a || {};
So i assume if a exists then assign a to b otherwise b is equal to an object. What i dont understand is where i will use this and how it differs to a ternary operator, isn't the short circuit evaluation the same as:
Example 2:
var a = true;
var b = (a) ? a : {};
Why would one use example 1 over example 2 as it isn't any slower to write out or is there a speed benefit of the use of one over the other? or is this just a silly question and perhaps i'm missing something. If someone could clear this up for me that would be great.
Share Improve this question asked Nov 4, 2016 at 0:34 bill fredbill fred 1591 gold badge2 silver badges6 bronze badges 7- 3 This only matters when the second operand has side-effects. – Ergwun Commented Nov 4, 2016 at 0:37
- Use whichever one you want. The time you've already spent thinking about it will be greater than any cumulative difference in typing or execution. – user1106925 Commented Nov 4, 2016 at 0:40
-
Kinda unrelated, but as an experiment try doing
b = a && {};
and see what happens and try to understand why it happens. – Dimitris Karagiannis Commented Nov 4, 2016 at 0:43 -
@Ergwun Did you mean the first operand (
a
)? – Bergi Commented Aug 9, 2023 at 3:58 - @Bergi No, I was trying to say that short circuit evaluation behaviour is important when the second operand has side effect. See my answer below for an explanation. – Ergwun Commented Aug 9, 2023 at 6:41
2 Answers
Reset to default 7Both of your examples will result in b
being assigned the value of a
(true
), and both constructs avoid the evaluation of the final operand (which is {}
in each case).
However, there are differences in readability and evaluation.
Readability:
I'd argue that if (a || b) { ... }
is more readable than if (a ? a : b) { ... }
).
Operand evaluation:
In (a || b)
, a
is only evaluated once. In (a ? a : b)
, a
is evaluated twice. This bees important when instead of a simple variable you are using an function or other expression:
// Costly double evaluation
var a = someExpensiveFunction()
? someExpensiveFunction()
: {};
// Less costly single evaluation
var a = someExpensiveFunction() || {};
More generally, short circuit operators can help you:
- avoid errors by only evaluating the second operand when it is safe:
var a = a && someFunctionThatWillThrowIfAIsNull(a);
- avoid slow functions under certain conditions by placing them as the second operand:
// Slower
var a = someSlowFunction() || someFastFunction();
// Faster
var a = someFastFunction() || someSlowFunction();
Here is an example the different usages (depending on the first parameter). Check the console for each of them to understand the way they work.
console.log("'' || {}:", '' || {});
console.log("1 || {}:", 1 || {});
console.log("0 || {}:", 0 || {});
console.log("true || {}:", true || {});
console.log("false || {}:", false || {});
console.log("[] || {}:", [] || {});
console.log('');
console.log("('') ? '' : {}:", ('') ? '' : {});
console.log("(1) ? 1 : {}:", (1) ? 1 : {});
console.log("(0) ? 0 : {}:", (0) ? 0 : {});
console.log("(true) ? true : {}:", (true) ? true : {});
console.log("(false) ? false : {}:", (false) ? false : {});
console.log("([]) ? [] : {}:", ([]) ? [] : {});
console.log('');
console.log("'' && {}:", '' && {});
console.log("1 && {}:", 1 && {});
console.log("0 && {}:", 0 && {});
console.log("true && {}:", true && {});
console.log("false && {}:", false && {});
console.log("[] && {}:", [] && {});