Operators & Expressions

Operators & Expressions

Operators and expressions are the fundamental building blocks of JavaScript logic. If variables are the "nouns" of your code, operators are the "verbs" that act upon them. An expression is any valid unit of code that resolves to a single value.

This chapter provides a deep dive into how JavaScript manipulates data, makes comparisons, and evaluates complex logic.


Why This Topic Matters

Operators and expressions appear in every single line of meaningful code, from simple math to complex business logic. Understanding them deeply will:

  • Prevent Coercion Bugs: Knowing when 5 + "5" becomes "55" and when it doesn't.
  • Improve Readability: Mastering short-circuit logic and ternary operators makes code cleaner.
  • Boost Debugging Speed: Understanding operator precedence helps you spot logic errors faster.
  • Modernize Your Code: Utilizing optional chaining and nullish coalescing prevents "cannot read property of undefined" crashes.

How To Study This Chapter

  1. Read the Concept: Understand the "why" before the "how".
  2. Examine the Examples: Look at the input and predict the output.
  3. Experiment: Open your browser console (F12) and try the edge cases mentioned.
  4. Visualize: Use the diagrams to build a mental model of how data flows through expressions.

Arithmetic Operators

Arithmetic operators perform standard mathematical calculations.

OperatorNameDescriptionExample
+AdditionAdds values or concatenates strings10 + 5 (15)
-SubtractionSubtracts the right from the left10 - 5 (5)
*MultiplicationMultiplies values10 * 5 (50)
/DivisionDivides the left by the right10 / 5 (2)
%Remainder (Modulo)Returns the integer remainder of division10 % 3 (1)
**ExponentiationRaises the left to the power of the right2 ** 3 (8)

Under the Hood: The Floating Point Problem

JavaScript uses the IEEE 754 standard for numbers, which represents all numbers as 64-bit floats. This leads to a famous "quirk":

console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false

Lesson: Never compare floating-point numbers directly for equality. Instead, check if the difference is smaller than a tiny value (called Number.EPSILON).


Assignment Operators

Assignment operators assign a value to the left-hand operand based on the value of the right-hand operand.

The Basic Assignment

let x = 10; — The value 10 is stored in the memory location labeled x.

Compound Assignments

These are shortcuts for performing an operation and then assigning the result back to the variable.

let score = 50;

score += 10; // Same as: score = score + 10; (Result: 60)
score -= 5;  // Same as: score = score - 5;  (Result: 55)
score *= 2;  // Same as: score = score * 2;  (Result: 110)
score /= 10; // Same as: score = score / 10; (Result: 11)

Note: The assignment operation itself is an expression that returns the assigned value. This allows for patterns like a = b = c = 5;.


Comparison & Relational Operators

Comparison operators return a boolean value (true or false).

Strict vs. Abstract Equality

This is a critical distinction in JavaScript.

  1. Strict Equality (===): Returns true only if both the value and the type are identical.
  2. Abstract Equality (==): Attempts to convert the types (coercion) before comparing values.

Abstract (==)"5" == 5 → TRUEnull == undefined → TRUE0 == false → TRUEPerforms Type CoercionStrict (===)"5" === 5 → FALSEnull === undefined → FALSE0 === false → FALSESafe & Predictable

Relational Operators

These test the relationship between values or properties.

  • in: Checks if a property exists in an object.
    const user = { name: "Alice" };
    console.log("name" in user); // true
    
  • instanceof: Checks if an object is an instance of a specific class/constructor.
    const now = new Date();
    console.log(now instanceof Date); // true
    

Logical Operators & Coercion

Logical operators are used to determine the logic between variables or values.

Truthy vs. Falsy

In JavaScript, every value is inherently "truthy" or "falsy" when evaluated in a boolean context.

The 6 Falsy Values:

  1. false
  2. 0 (and -0, 0n)
  3. "" (empty string)
  4. null
  5. undefined
  6. NaN

Everything else is truthy, including [], {}, and "0".

Short-Circuit Evaluation

Logical operators return the value that decided the outcome.

  • AND (&&): Returns the first falsy value, or the last value if all are truthy.
  • OR (||): Returns the first truthy value, or the last value if all are falsy.

AND (&&)TruthyFalsyStop & Return FalsyShort-circuiting skips unnecessary evaluations.

const name = "Alice";
const greeting = name && `Hello, ${name}`; // "Hello, Alice"
const defaultUser = "" || "Guest";         // "Guest"

Modern Operators: Nullish & Optional Chaining

Modern JavaScript (ES2020+) introduced operators to solve common "value missing" problems safely.

Nullish Coalescing (??)

Unlike ||, ?? only triggers on null or undefined. This is safer for numbers (0) or empty strings.

let count = 0;
let result1 = count || 10; // 10 (because 0 is falsy)
let result2 = count ?? 10; // 0  (because 0 is NOT null/undefined)

Optional Chaining (?.)

Safely access deep properties. Returns undefined if any link in the chain is nullish.

const user = { profile: { name: "Bob" } };
const zip = user?.address?.zip; // undefined (no crash!)

Advanced & Utility Operators

Bitwise Operators

Act on the 32-bit binary representation of numbers.

  • & (AND), | (OR), ^ (XOR), ~ (NOT).
  • << (Left Shift), >> (Right Shift).

Utility Operators

  • delete: Removes a property from an object.
  • void: Evaluates an expression and returns undefined.
  • Comma (,): Evaluates multiple expressions and returns the last one. let x = (1, 2, 3); // x is 3

The Ternary Operator

The only JavaScript operator that takes three operands.

Syntax: condition ? exprIfTrue : exprIfFalse

const status = age >= 18 ? "Adult" : "Minor";

Unary Operators

  • typeof: Returns a string of the value type.
  • ! (NOT): Negates truthiness. !! converts any value to a boolean.
  • + (Unary Plus): Coerces values to numbers.
  • ++ / --: Increment/Decrement (Prefix vs Postfix).

Operator Precedence & Associativity

PriorityOperatorDescriptionAssociativity
1( )Groupingn/a
2. / ?. / [] / ()Property / CallLeft-to-Right
3++ / -- / ! / typeof / void / deleteUnaryRight-to-Left
4**ExponentiationRight-to-Left
5* / / / %MultiplicativeLeft-to-Right
6+ / -AdditiveLeft-to-Right
7<< / >>Bitwise ShiftLeft-to-Right
8< / <= / > / >= / in / instanceofRelationalLeft-to-Right
9=== / !== / == / !=EqualityLeft-to-Right
10&&Logical ANDLeft-to-Right
11`/??`
12? :TernaryRight-to-Left
13= / +=AssignmentRight-to-Left
14,CommaLeft-to-Right

Common Mistakes & Pitfalls

  1. Assignment in a Condition: if (x = 5) assigns instead of compares.
  2. String Concatenation: 1 + 2 + "3" is "33".
  3. NaN Comparison: NaN === NaN is false. Use Number.isNaN().

Mini Exercises

  1. The Mystery Result: Predict the result of 10 + 5 * 2 / (4 - 2).
  2. Short-Circuit Challenge: What does "Orange" && 0 || "Apple" return? Why?
  3. Safety First: Refactor user && user.address && user.address.zip using optional chaining.
  4. Ternary Toggle: Write a ternary that returns "Light Mode" if isDark is false, and "Dark Mode" if it's true.
  5. Coercion Trap: Explain why [] == ![] is true. Hint: ![] is false. [] == false triggers coercion. Both become 0.

Review Questions

  1. Why should you avoid using == for comparing numbers and strings?
  2. What is the difference between null || "default" and null ?? "default"?
  3. How does x++ differ from ++x in a console.log statement?
  4. What are the six purely "falsy" values in JavaScript?
  5. In a || b && c, which part evaluates first?

Reference Checklist

  • I understand why 0.1 + 0.2 is not 0.3.
  • I can explain the difference between == and ===.
  • I know how to use ?? for defaults without blocking 0.
  • I can use ?. for safe navigation.
  • I understand short-circuiting for && and ||.
  • I know how to use parentheses to override precedence.