Understanding Operator Precedence and Associativity in JavaScript

This article is a complementary resource to the Learn JavaScript Basics course.

Understanding Operator Precedence and Associativity in JavaScript

In JavaScript, operator precedence and associativity determine the order in which operations are performed in an expression.

Consider the following expression:

let result = 10 - 5 + 3 * 2;
console.log(result);

It's very difficult to determine the result of the above code. But the way JavaScript evaluates it is:

10 - 5 + 3 * 2
= 10 - 5 + 6
= 11

Here, the order of operations is:

  1. multiplication
  2. addition
  3. subtraction

The rules JavaScript follows to evaluate any expression are provided by operator precedence and associativity.


Operator Precedence Table

Here's an overview of operator precedence in JavaScript (from highest to lowest):

Operator Description Precedence
() Parentheses Highest
** Exponentiation High
*, /, % Multiplication, Division, Modulo Medium
+, - Addition, Subtraction Lower
<, >, <=, >= Comparisons Low
==, !=, ===, !== Equality/Inequality Lowest

What is Operator Associativity?

Associativity determines how operators of the same precedence are evaluated.

JavaScript follows two types of associativity:

  • Left-to-right associativity: Most operators, like +, -, *, and /, are evaluated from left to right.
  • Right-to-left associativity: Operators like exponentiation (**) and assignment (=) evaluate from right to left.

Example: Left-to-Right Associativity

Consider the following expression:

let result = 20 - 5 - 3;
console.log(result);    // Output: 12

Here, subtraction is evaluated left to right: (20 - 5) - 3 = 12.

Now, let's look at another example:

let result = 10 / 2 * 3;
console.log(result);    // Output: 15

In this case, both multiplication (*) and division (/) share the same precedence and are evaluated from left to right. So, division is performed first:

(10 / 2) * 3 = 15

Example: Right-to-Left Associativity

Exponentiation is right-to-left associative. Let's see an example,

let result = 2 ** 3 ** 2;
console.log(result);    // Output: 512

This is evaluated as 2 ** (3 ** 2).


Ambiguity in Complex Expressions

Without understanding precedence, it's easy to make mistakes. For example:

let result = 10 / 2 / 2;
console.log(result); 

You might expect 10.0, but JavaScript evaluates it as (10 / 2) / 2 = 5 / 2 = 2.5.

To avoid such errors, always use parentheses to clarify your intentions.

let result = 10 / (2 / 2);
console.log(result);    // Output: 10

Takeaway

To avoid confusion and ensure clarity, always use parentheses to explicitly define the order of operations in complex expressions. For example:

let result = 30 / (2 * 3);
console.log(result);    // Output: 5

Here, parentheses ensure that 2 * 3 is evaluated first, changing the result of the division. Without parentheses, the division would be performed first, leading to a different result.

Using parentheses clarifies your intentions, eliminates ambiguity, and helps prevent logic errors.