JavaScript Operator Precedence Rules Explained

JavaScript operator precedence determines the sequence in which operators are parsed and evaluated within an expression. Understanding these rules is essential for writing predictable code, avoiding subtle logic bugs, and knowing when to use grouping parentheses to override default evaluation behavior. This guide outlines the core hierarchy of operator precedence, associativity rules, and common evaluation patterns in JavaScript.

Understanding Precedence and Associativity

When an expression contains multiple operators, JavaScript uses two mechanisms to resolve the evaluation order:

  1. Precedence: Operators with higher precedence are evaluated before operators with lower precedence. For example, in 3 + 4 * 2, the multiplication operator (*) has higher precedence than addition (+), resulting in 3 + 8 = 11.
  2. Associativity: When operators have the same precedence level, associativity determines the direction of evaluation:
    • Left-to-Right (Left-associative): The expression is resolved from left to right (e.g., a - b - c evaluates as (a - b) - c).
    • Right-to-Left (Right-associative): The expression is resolved from right to left (e.g., a = b = c evaluates as a = (b = c), and 2 ** 3 ** 2 evaluates as 2 ** (3 ** 2)).

Operator Precedence Hierarchy

The table below lists JavaScript operators ordered from highest precedence (evaluated first) to lowest precedence (evaluated last):

Precedence Level Operator Type Syntax Examples Associativity
19 (Highest) Grouping ( ... ) N/A
18 Member Access / Calls obj.prop, obj[prop], fn(), new fn() Left-to-right
17 Optional Chaining / new (no args) obj?.prop, new fn Left-to-right
16 Postfix Increment / Decrement x++, x-- N/A
15 Prefix / Logical NOT / Unary / Type ++x, --x, !x, +x, -x, typeof, void, delete, await Right-to-left
14 Exponentiation ** Right-to-left
13 Multiplicative *, /, % Left-to-right
12 Additive +, - Left-to-right
11 Bitwise Shift <<, >>, >>> Left-to-right
10 Relational / Type Testing <, <=, >, >=, in, instanceof Left-to-right
9 Equality ==, !=, ===, !== Left-to-right
8 Bitwise AND & Left-to-right
7 Bitwise XOR ^ Left-to-right
6 Bitwise OR \| Left-to-right
5 Logical AND && Left-to-right
4 Logical OR / Nullish Coalescing \|\|, ?? Left-to-right
3 Conditional (Ternary) condition ? val1 : val2 Right-to-left
2 Assignment / Logical Assignment =, +=, -=, **=, &&=, \|\|=, ??= Right-to-left
1 (Lowest) Comma , Left-to-right

Key Precedence Rules to Remember

1. Logical Operators Follow a Strict Hierarchy

Logical NOT (!) runs before Logical AND (&&), which runs before Logical OR (||):

const result = !false && false || true;
// Step 1: (!false) -> true
// Step 2: (true && false) -> false
// Step 3: (false || true) -> true

2. Nullish Coalescing (??) and Logical Operators

JavaScript explicitly forbids combining ?? directly with && or || without explicit parentheses to prevent ambiguity. Doing so throws a SyntaxError:

// SyntaxError:
// const value = a || b ?? c;

// Correct usage:
const value = (a || b) ?? c;

3. Exponentiation is Right-Associative

Unlike most arithmetic operators, exponentiation executes from right to left:

const result = 2 ** 2 ** 3;
// Evaluates as 2 ** (2 ** 3) -> 2 ** 8 = 256
// Not (2 ** 2) ** 3 -> 4 ** 3 = 64

4. Assignment Has Low Precedence

Assignment operators are near the bottom of the precedence table, ensuring expressions to the right of the = operator are fully computed before the variable receives the value:

let total;
total = 10 + 5 * 2; 
// 5 * 2 = 10 -> 10 + 10 = 20 -> total = 20

Best Practice: Use Parentheses for Clarity

While memorizing the precedence table is useful, relying on implicit precedence in complex expressions makes code harder to read and maintain. Wrapping sub-expressions in parentheses (()) clearly communicates intent and removes ambiguity for both the JavaScript engine and future maintainers.