Short-circuit evaluation in JS (part 1)

Andrey Zakharov
04-02-2018

Hi there. Today I’m going to show one cool feature of JavaScript which is based on interesting behaviour (as usual) of JS. You’ll get advanced knowledge of boolean logic in JS and finally learn how to apply this to make a transaction (mostly) in your application.

Into theory

First of all, let’s dig into js theory. Take a look on this example:

var firstCompound = false,
secondCompound = true,
lastCompound = true;

function getResult() {
    return firstCompound && secondCompound && lastCompound;
}

Pretty familiar, right? Well, it’s also easy to calculate the result by yourself. If a boolean expression contains at least one false in a chain of AND operators, it makes the result false. And that’s fascinating news – JS also uses such heuristic rule to calculate boolean result. When parser meets “false” value in a such expression, it won’t calculate anything further, it will return “false” immediately. In our case it stops calculating on a first variable firstCompound and won’t touch values of secondCompound and lastCompound. Even it’s undefined, we’ll get false as a result (don’t believe me, try it by yourself in browser console). By the way, what will be the result if all variables are undefined? Better to check now.

This approach is called “short-circuit” evaluation. The intention of this approach is to reduce the load of browser. That’s obviously good, but we can also use this side-effect for our own purpose.

Make a transaction

Imagine, each compound is not a predefined value, but a function. Each function can make some actions and return a result. It may looks like this:

function stepOne() {
     console.log('step one is done');
     return false;
}

function stepTwo() {
     console.log('step two is done');
     return true;
}

function stepThree() {
    console.log('step three is done');
    return true;
}

function performSteps() {
    return stepOne() && stepTwo() && stepThree();
}

performSteps();

I guess, you already know what will happen here. We will see only ‘step one is done’, because stepOne() returns ‘false’ and js will apply short-circuit here. Well, the name “transaction” is not so applicable here. If you familiar with databases theory, you may know that transaction is a unit of work, which could contain several actions. In case one of actions was failed, transaction should stop immediately and all previous steps performed in transaction already should be cancelled. Here we have an implementation of the first part of transaction. In case one of steps returns false, we’ll stop doing all further steps. If you have an idea how to implement the second rule of transaction, share it in comments!

So, I guess you can find this solution useful in your scripts. Last thing I want to note that you can still use the result boolean value for monitoring purpose. Take a look on performSteps() function. It returns boolean value actually and this value represents a result of performing steps. If result is false, it means that some step failed. If result is true, we know that all steps performed successfully. So, we can notify user about it:

var isDone = performSteps();

if (isDone) {
    console.log('The task was completely done');
} else {
    console.error('Some step of the task was failed');
}

Troubleshouting

You should take care of returned values in such boolean structure, especially when you’re using functions. That’s a more often case that you could think when function returns undefined value. On a business level it means actually that application (and you) doesn’t know exactly what was the result of some action. Was it successful? Was it wrong? We are not sure. Anyway we should be sure how our application behaves in such case.

Imagine, that our steps doesn’t have return line.

function stepOne() {
     console.log('step one is done');
}

function stepTwo() {
     console.log('step two is done');
}

function stepThree() {
     console.log('step three is done');
}

function performSteps() {
     return stepOne() && stepTwo() && stepThree();
}

performSteps();

Oops! Only first step will be performed. Each function doesn’t have visible returned value, but it has anyway, and this is undefined. Again, don’t believe me, try it by yourself in console (Didn’t I already ask to check what would be the result of boolean chain in case variables are undefined?).

How to avoid awkward undefined values in your js application more elegantly? That’s also can be solved by another trick using short-circuit evaluation. I will tell you about it in the next part of this topic. Meanwhile, you can dig into current solution of transaction and think about if it’s possible to make it reversible. Have a nice coding!

LEAVE A REPLY

you might also like