Getting Caught Out With Operator Precedence in Javascript

Adam Drake
4 min readJul 15, 2024

--

AI going a little off the mark but this is supposed to be a ternary operator dancing with a pipe sign

In software you sometimes come across some code that you are sure should work and for some strange unknown reason it just doesn’t. You scratch your head. You go for a coffee. You come back and get down to work.

You play around with console.logs and slowly but surely you narrow down on where the troublesome piece of code might be. It’s a detective game and one of the elements of coding that I really enjoy, although it can be rather frustrating sometimes.

Usually you find the piece of code, realise pretty quickly what the issue is and then you can go about fixing it. However, on this occasion I found the code after a little while of hunting, but I was stumped as to what the issue might have been. Turns out it had to do with operator precedence.

This is the code:

const purity = compound.purity || compoundRole === TARGET_PRODUCT ? null : 100

This is the logic I was going for:

If the compound‘s purity value exists then that should be used and if not, then if the compoundRole is a TARGET_PRODUCT then the default value should be null and if not then the default value should be 100.

Can you work out what is wrong with this code?

The Issue

The issue in my logic was due to the operator precedence of the || (logical OR) and ?: (ternary) operators in JavaScript. The || operator has higher precedence than the ?: operator, which meant that the expression was evaluated in a way I didn’t intend.

My original code:

const purity = compound.purity || compoundRole === TARGET_PRODUCT ? null : 100

was being evaluated as:

const purity = (compound.purity || compoundRole === TARGET_PRODUCT) ? null : 100

So, for example when compound.purity is 80, the 80 value is truthy, and the left side of the || operator (compound.purity) will be taken as true, thus making the ternary expression evaluate to null.

To fix this I had to explicitly wrap the second part of the code in parentheses like so:

const purity = compound.purity || (compoundRole === TARGET_PRODUCT ? null : 100)

This way I was able to override the default precedence in Javascript.

Exploring Further

I was curious about this precedence of operators, especially for logical operators and conditional operators so I started exploring more.

Logical and Conditional operators and their order of precedence:

  1. && — Logical AND
  2. || — Logical OR
  3. ?? — Nullish Coalescing
  4. ? : — Conditional/Ternary

This is super interesting and just highlights to me how careful you have to be when combining logical and conditional operators together. We can see more with some examples:

let a = true;
let b = false;
let c = true;
let result = a && b || c; // (a && b) || c
console.log(result); // Output: true

If we reverse the operators we start getting into the area where you can easily trip up.

let a = true;
let b = false;
let c = false;
let result = a || b && c; // a || (b && c)
console.log(result); // Output: true

You might be inclined to read this left to right but if you did you would probably end up reading the code wrong and thinking it did something else.

Last but not least, an example with the ternary operator:

let a = true;
let b = false;
let result = a ? b || true : false; // a ? (b || true) : false
console.log(result); // Output: true

Conclusion

Having spent some time digging a little deeper into logical and conditional operators I think it’s important to be aware of operator precedence and how it can affect your code. It can be very easy to start combining these operators and then introduce a bug into your code.

These are the kind of details we need to be aware of on a day to day basis when developing and a little knowledge can go a long way.

Subscribe to My Weekly Updates!

Enjoyed This Post?

If you found this blog post helpful, why not stay updated with my latest content? Subscribe to receive email notifications every time I publish. New posts go live every Monday at 8:30 AM Central European Time.

What You’ll Get

By subscribing, you’ll get:

  • Exciting Discoveries: Be the first to know about the latest tools and libraries.
  • How-To Guides: Step-by-step articles to enhance your development skills.
  • Opinion Pieces: Thought-provoking insights into the world of frontend development.

Join Our Community

I live in the vibrant city of Prague, Czech Republic, with my family. My blog is more than just articles; it’s a community of like-minded developers who share a love for innovation and learning.

About me

I’m a passionate Frontend Developer specialising in React and TypeScript. My professional journey revolves around exploring and mastering new tools and libraries within the JavaScript ecosystem.

Check out the original blog post on my blog.

Check out my LinkedIn and Github if you are interested.

--

--

Adam Drake

I'm a Frontend Developer and I write about all things Frontend Related - Think lightly of yourself and deeply of the world. Based in Prague, CZ