Remember that AND has a higher precedence than OR

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the dumb-mistakes-and-gotchas category.

Last Updated: 2024-04-24

I had the following code for triggering an email gathering pop-up and hiding it when an email was already given or the pop-up was already dismissed.

if(!gaveEmail() && !isDismissed() && (isScrolledFarEnough && secondsOnPage > 30) || secondsOnPage > 60) {
  showPopup()
}

Unfortunately, even after someone dismissed the pop-up, it still kept showing. Why?

Simplifying a bit into a more algebraic form, the above line is essentially:

 a && b && (c && d) || e

Because && has a higher precedence than ||, these && bits are evaluated first, from left to right. We can demonstrate that by adding parentheses:

((a && b) && (c && d)) || e

Now it should be clear that the pop-up will always show if condition e is true. Referencing my original code, this means that the pop-up will always show if secondsOnPage > 60. And therein lies my bug.

Lesson