Does JavaScript Have "Short-Circuit" Evaluation

Does JavaScript have Short-circuit evaluation?

Yes, JavaScript has "short-circuit" evaluation.

if (true == true || foo.foo){
// Passes, no errors because foo isn't defined.
}

Live DEMO

if (false && foo.foo){
// Passes, no errors because foo isn't defined.
}

Live DEMO

Why does short-circuit evaluation work when operator precedence says it shouldn't?

Or am I confusing matters?

You are. I think it's much simpler to think about precedence as grouping than ordering. It affects the order of evaluation, but only because it changes the grouping.

I don't know about Javascript for sure, but in Java operands are always evaluated in left-to-right order. The fact that == has higher precedence than || just means that

true || foo == getValue()

is evaluated as

true || (foo == getValue())

rather than

(true || foo) == getValue()

If you just think about precedence in that way, and then consider that evaluation is always left-to-right (so the left operand of || is always evaluated before the right operand, for example) then everything's simple - and getValue() is never evaluated due to short-circuiting.

To remove short-circuiting from the equation, consider this example instead:

A + B * C

... where A, B and C could just be variables, or they could be other expressions such as method calls. In Java, this is guaranteed to be evaluated as:

  • Evaluate A (and remember it for later)
  • Evaluate B
  • Evaluate C
  • Multiply the results of evaluating B and C
  • Add the result of evaluating A with the result of the multiplication

Note how even though * has higher precedence than +, A is still evaluated before either B or C. If you want to think of precedence in terms of ordering, note how the multiplication still happens before the addition - but it still fulfills the left-to-right evaluation order too.

Why does this short circuit evaluation return undefined if first value is false?

In your updated example, the logical AND … && … has a higher order of precedence (5) than the evaluation of the ternary … ? … : … (3).

Check out the table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table

using Short-Circuiting ( || ) in Object in JavaScript

The non-descriptive variable names don't really help to explain the situation. Let's start of by rewriting the code with more descriptive variable names.

const game = {
score: "4:0",
scored: ["Lewandowski", "Gnarby", "Lewandowski", "Hummels"],
};

const goals = {};
for (const player of game.scored) {
goals[player]++ || (goals[player] = 1);
}

console.log(goals);

goals[player]++ increments the goals for player by 1 and returns the old value. The tricky thing in goals[player]++ is that player might not be present in goals yet. In which case undefined is returned (which is falsy). Because the value is falsy the second operand of the OR operator will be executed. (goals[player] = 1) will set the goals for player to 1.

The code is essentially counting how often a specific name is present in the game.scored array. The presence of a name symbolises a goal made by them.

A less cryptic way of writing similar code would be:

const goals = {};
for (const player of game.scored) {
if (player in goals) {
goals[player] += 1; // add 1 to the current score
} else {
goals[player] = 1; // no score present so use 1
}
}

However I usually prefer to set a default value, this way you don't have to split the logic into two actions:

const goals = {};
for (const player of game.scored) {
goals[player] ||= 0; // assign 0 if the current value is falsy
goals[player] += 1; // add 1 to the current value
}

Note that ||= is fairly new, if you write JavaScript for older browser you can use the following instead:

if (!goals[player]) goals[player] = 0;

Short circuit evaluation and assigning either true or false to a variable

You can use the nullish coalescing operator instead.

let finalConfig = preloadedConfig.configA ?? true;

Alternatively, you can use a hasOwnProperty check.

let finalConfig = preloadedConfig.hasOwnProperty('configA') ? preloadedConfig.configA : true;

One-line short-circuit evaluation with && || in JavaScript

This one-liner is the equivalent of saying:

var prefix;
if(options && options.prefix){
prefix = options.prefix;
} else{
prefix = '';
}

Short-Circuit Evaluation of Logical Expressions in JavaScript

x is 5 which is binary 101, (x >>= 5) is therefore zero, x is assigned zero, and y++ in the first statement is not executed.

(x << 5) is likewise zero since x is now zero, so the y++ in the second statement also does not execute. The value of y remains 10, since no y++ is executed.

I don't know where your author is getting y == 11 from, it's wrong.

The IDE error is a red herring - it does not understand your file contains javascript (or you delimiited the javascript incorrectly) and is trying to parse it as XML / HTML.

Cleanest way to assign with short circuit evaluation on multiple conditions

You can chain ternary operators

    shipToAddLine: addresses ? addresses[0].shipToAddLine : (cart ? cart.shipToAddLine : null),

Short circuit evaluation in JavaScript - SyntaxError: Unexpected token 'return'

The right hand side of && needs to be an expression. You're trying to put a statement there.

The && has to evaluate as something but return x doesn't give you a value. It exits the function and passes its RHS to the calling function.



Related Topics



Leave a reply



Submit