How to Write Faster JavaScript Condition Expressions

There’s an interesting optimization feature in JavaScript which doesn’t necessarily apply in other languages. Consider the following code sample:


var x = 10;
var y = true;

if (x*x > 1000 || y) alert("true!");

As you’d expect, “true” is output because y is true — even though the first condition fails.

JavaScript interpreters analyze each condition in sequence. If we changed x to 100, x*x would be greater than 1000 and evaluate to true. But, because we’re using a logical OR (||), the interpreter never needs to analyze y — the expression must be true so the alert is displayed.

Therefore, we can optimize expressions to ensure those which require the least processing are analyzed first, i.e.


if (y || x*x > 1000) alert("true!");

If y is true, the interpreter will never need to evaluate the second condition. That could save considerable time, especially if we were calling a function, performing intensive calculations or analyzing the DOM.

The same optimization applies to logical AND (&&). In that case, the first expression which evaluates to false makes the whole condition false — no further processing is required.

Assignments inside conditions

James Edwards recently wrote the article Assignment inside a Condition where he discussed code such as…


if (summary = document.getElementById("post-summary")) {
	alert(summary.innerHTML);
}

The summary variable is set to the HTML element with an ID of “post-summary”. If the element exists, the condition evaluates to true and the alert appears. If an element cannot be found, the condition evaluates to false and none of the conditional code is executed.

It’s a useful technique although, according to the comments, few developers liked the practice because it makes JavaScript more difficult to read and debug.

However, there’s another issue — with 2 or more conditions, your assignment may never execute. For example:


if (x || y = functionY()) {
	alert(y);
}

If x evaluates to true, the interpreter never assigns a value to y and the alert will always throw an error.

We could fix it by reversing the conditions so y is always evaluated, e.g.


if (y = functionY() || x) …

Even then, it could still cause confusion because it’s not obvious that the ordering of these conditions is essential. A developer who read the top half of this article might even attempt to optimize the code by evaluating x first!

In summary, if you want to use assignments inside conditions, go ahead — but be absolutely sure it’s the only condition you’ll ever need!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.deathshadow.com deathshadow60

    I find this article confusingly pointless — especially since not once does it even use the proper term for what’s being discussed; SHORT CIRCUIT EVALUATION.

    Which frankly is programming 101, if you’ve not heard of it then you need to go back to basics… less than basics.

    As to the “few developers liked the practice because it makes JavaScript more difficult to read and debug.” nonsense when it comes to assignment evaluations, that must only apply to javascript programmers as it’s a common structure in all C dialect languages and the norm amongst real programmers. If that’s ‘difficult’ it’s because whoever said that doesn’t know enough programming to be opening their mouth on the subject.

    In any case the article doesn’t actually seem to say anything about what would increase the speed — which is prioritizing your evaluation order. The most commonly true statement of an expression should go first, so the less common ones are evaluated less often. That’s it, that’s all you need to say.

    • Arkh

      I have to agree with deathshadow. Short circuit evaluation is something really basic which you can find in a lot of programming languages.

    • Sam Foster

      FWIW jslint warns about using ‘=’ in a conditional expression because its a common typo to say ‘=’ when you mean ‘==’, and a potentially nasty bug to track down if you do make that mistake. It suggests you use ((a = b)) if you really mean to test the result of the assignment.

      • JustinJohnson.org

        It’s a common typo *and* it decreases readability. Write clean code first.

        Sorry Craig, I have to question the usefulness of this article. Putting a buzzy title on an elementary subject doesn’t make it any less elementary and all that much more disappointing.

    • lorenz

      agreed.

    • Scott Anderson Regitz

      I agree. Short-Circuit logic has been around for a LONG time and is a commonly used tool in most programming languages (by responsible programmers)

  • http://www.cemerson.co.uk Stormrider

    I think all of the above applies to PHP as well

    • http://www.dmgx.com Michael Morris

      It applies to all members of the ALGOL family – PHP, C and it’s derivatives, Java, JavaScript. More than a few other languages use this.

      @Death Shadow, you’re being unnecessarily harsh.

      Also, I’ve never heard this called ‘short circuit’ evaluation, but I have heard it called “Lazy Evaluation.” — The interpretter/compiler evals just enough of the statement to know the outcome and no more.

      Note — Or isn’t the only boolean operation affected – they all are.

  • Tom

    Thanks. This is a simple and short explanation that I found useful. Thanks to Arkh and deathshadow for putting a name to the technique.

  • Demis

    eh… having side-effects in your conditional logic is a recipe for buggy code.

  • “Cowboy” Ben Alman

    Craig, this is invalid, and you’ll get an “invalid left-hand side in assignment” error:

    x || y = functionY()

    You need to use parens, like so:

    x || ( y = functionY() )

    • http://www.deathshadow.com deathshadow60

      Depends on the browser actually, but yer right, a few of them will choke on it.

      Technically an assignment operation should take precedence over the bitwise comparison just like how multiplications are run before addition; but many JS interpreters aren’t as bright as say… a C compiler.

  • Frank

    “doesn’t necessarily apply in other languages”…
    I think it is easier to find languages where it applies than where it doesn’t.

  • http://codefisher.org/ codefisher

    Never ever seen a programming language where this does not apply. So I don’t see why you would say that?? Can you name one?

    As said above, a rather lame article. Not the quality I normally come looking for here.

    • dwntrdr

      codefisher: Unfortunately, classic Visual Basic used to evaluate every condition regardless. I’m not sure what VB.Net does, thankfully I no longer code in that language!

  • Laugh Out Louder

    LOL. For whatever reason, when I read this I felt like the author was conveying excitement as though this was a groundbreaking discovery.

  • Shazam

    I appreciate the authors time to write this article, but it seems deathshadow has managed to sum it up rather simply….

    “The most commonly true statement of an expression should go first, so the less common ones are evaluated less often.”

    That is all I really needed to read, although I commend your article for stimulating the conversation.

  • http://www.optimalworks.net/ Craig Buckler

    Thanks for all your comments. I’m sorry to those who found it too basic, but SitePoint is a resource for developers at all levels.

  • 3DVector

    i think that’s not basics for all readers , some people forget that in programming there’s amateurs and professionals!
    and as amateur i find this very helpful and didn’t know it before because i learn programming by myself and didn’t taken any formal course!