Saturday, July 9, 2016

JavaScript not evaluating all functions in condition

I’ve just been struck by a simple though nuance code optimization. I’ve met it probably thousands times. In fact, some style guides I’ve followed forbids to do what I’ve just done ;-)

First let me explain what we want to achive. We want to call 3 functions and early return if all 3 returned false. Does the below code look good for you?

if (!func0() && !func1() && !func2()) {
    return;
}

Unfortunately it’s wrong. The JavaScript execution engine will optimize it and if the func0 call returns true (negated by !) then the func1 and func2 won’t be called at all.

This phenomenon has a name and it’s called short-circut evaluation, quoting Wikipedia:

the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression

This applies to third and further arguments. Thus the lesson is: never put function calls in logical statements, at least not functions you want guarantee to be executed.

Changed code:

var skip = !func0();
skip &= !func1();
skip &= !func2();
if (skip) {
    return;
}

I’m sure the world is full of this kind of bugs.