Chapter 4: JS Operators & Expressions
Operators are the computational engine of JavaScript. They allow you to perform arithmetic calculations, assign values, compare data, evaluate complex logic conditions, and leverage modern ES features like the Nullish Coalescing (??) and Optional Chaining (?.) operators.
4.1 Arithmetic & Assignment Operators
Arithmetic operators take numeric values (either literals or variables) as their operands and return a single numeric value. Compound assignment operators evaluate and assign results in a single step.
| Operator | Name | Example Expression | Result | Equivalent Assignment |
|---|---|---|---|---|
+ |
Addition | 15 + 5 |
20 | x += 5 (x = x + 5) |
- |
Subtraction | 20 - 8 |
12 | x -= 8 (x = x - 8) |
* |
Multiplication | 6 * 7 |
42 | x *= 7 (x = x * 7) |
/ |
Division | 20 / 4 |
5 | x /= 4 (x = x / 4) |
% |
Modulus (Remainder) | 17 % 5 |
2 | x %= 5 (x = x % 5) |
** |
Exponentiation (ES2016) | 2 ** 3 (2³) |
8 | x **= 3 (x = x ** 3) |
Critical Pitfall: Prefix (++x) vs Postfix (x++)
Both increment the variable by 1, but they return completely different values in expressions:
let a = 5;
let b = a++; // b = 5, a becomes 6
let x = 5;
let y = ++x; // y = 6, x becomes 6
Arithmetic & Compound Assignment in Action
let cartTotal = 120;
let taxRate = 0.08; // 8% tax
let discount = 15;
// Compound calculations
cartTotal -= discount; // cartTotal is now 105
cartTotal *= (1 + taxRate); // cartTotal is now 113.4
console.log("Final Payable: $" + cartTotal.toFixed(2)); // $113.40
Try in Playground »
4.2 Comparison Operators: Strict (===) vs Loose (==)
Comparison operators test whether two values satisfy a condition and always return a boolean: true or false.
| Operator | Description | Example | Evaluation Result |
|---|---|---|---|
=== |
Strict Equality (Checks value AND data type) | 5 === "5" |
false (Number vs String) |
== |
Loose Equality (Performs implicit type coercion) | 5 == "5" |
true (coerced to 5 == 5) |
!== |
Strict Inequality (Type or value is not equal) | 5 !== "5" |
true |
!= |
Loose Inequality (Coerces before comparing) | 5 != "5" |
false |
> / >= |
Greater than / Greater than or equal | 10 >= 10 |
true |
< / <= |
Less than / Less than or equal | 4 < 3 |
false |
Golden Standard in Professional JavaScript
Always use strict equality === and strict inequality !==. Loose equality (==) triggers unpredictable type coercion rules (for example, 0 == false is true, and "" == false is true), which causes subtle bugs in production code.
=== avoids performance overhead and bugs by checking type identities upfront without triggering type coercion algorithms.
4.4 Logical Operators & Short-Circuit Evaluation
Logical operators are used to determine logic between variables or boolean expressions.
Returns true only if ALL operands are truthy.
true && true ➔ truetrue && false ➔ false
Returns true if AT LEAST ONE operand is truthy.
false || true ➔ truefalse || false ➔ false
Inverts boolean truth value. Double NOT !!x converts to boolean.
!true ➔ false!!"Alice" ➔ true
Short-Circuit Evaluation Rules
// 1. AND (&&) stops at first FALSY value and returns it
let user = { loggedIn: true, name: "Sanju" };
user.loggedIn && console.log("Welcome back, " + user.name); // Logs message
// 2. OR (||) stops at first TRUTHY value and returns it
let defaultTheme = null;
let activeTheme = defaultTheme || "dark-mode"; // Evaluates to "dark-mode"
4.5 Modern Operators: Ternary, Nullish Coalescing & Optional Chaining
Modern JavaScript (ES2020+) introduced elegant operators that dramatically simplify control logic and prevent runtime TypeError: Cannot read properties of undefined errors.
Inline if...else expression returning a value directly.
let age = 20;
let status = (age >= 18)
? "Adult"
: "Minor";
Returns right operand ONLY if left operand is null or undefined (preserves 0 and ""!).
let score = 0;
// || replaces 0 with 10 (Bug!)
let a = score || 10; // 10 ❌
// ?? preserves 0 correctly!
let b = score ?? 10; // 0 ✅
Safely accesses deeply nested object properties without throwing null reference errors.
let user = {};
// Returns undefined safely!
let city = user?.address?.city;
console.log(city); // undefined
4.6 Operator Precedence & Grouping
Operator precedence determines the order in which operators are parsed when evaluating an expression. Operators with higher precedence are evaluated first.
| Precedence Level | Operator Type | Symbols | Associativity |
|---|---|---|---|
| 1 (Highest) | Grouping / Parentheses | ( ... ) |
n/a |
| 2 | Member Access & Optional Chaining | . ?. [ ] |
Left-to-Right |
| 3 | Exponentiation | ** |
Right-to-Left |
| 4 | Multiplication / Division / Modulus | * / % |
Left-to-Right |
| 5 | Addition / Subtraction | + - |
Left-to-Right |
| 6 | Relational / Equality | < > === !== |
Left-to-Right |
| 7 | Logical AND | && |
Left-to-Right |
| 8 | Logical OR / Nullish Coalescing | || ?? |
Left-to-Right |
| 9 (Lowest) | Assignment | = += -= |
Right-to-Left |
💡 Pro Tip: When writing complex formulas, always use parentheses ( ) to make the evaluation order explicit, readable, and immune to precedence ambiguities.
4.7 Live Expression & Operator Inspector
Live SandboxSelect preset JavaScript operator expressions or type your own custom expression to test operator precedence, short-circuiting, and coercion results live.
4.8 Hands-on Challenge: Smart E-Commerce Discount Engine
Build an e-commerce price calculator that takes a base price, applies a coupon if present using the Nullish Coalescing (??) operator, checks if the customer qualifies for free shipping using logical AND (&&), and computes the final formatted total using a ternary operator.
Requirements:
- Declare
basePrice = 80,couponDiscount = 0(ornull), andisVipMember = true. - Use
couponDiscount ?? 5to ensure a $0 discount is NOT replaced by the default $5. - Use ternary to set
shippingFee = (basePrice >= 50 || isVipMember) ? 0 : 9.99. - Calculate final total:
(basePrice - discount) + shippingFee.
Need a Hint?
const discount = couponDiscount ?? 5; so that a coupon value of 0 is respected instead of falling back to 5. Then use ternary syntax const shipping = (subtotal >= 50 || isVip) ? 0 : 9.99;.
Reveal Full Solution
function calculateSmartTotal(basePrice, couponDiscount, isVipMember) {
// 1. Nullish coalescing preserves 0 discount
const discount = couponDiscount ?? 5;
// 2. Subtotal after discount
const subtotal = basePrice - discount;
// 3. Ternary operator for free shipping qualification
const shippingFee = (subtotal >= 50 || isVipMember) ? 0 : 9.99;
const finalTotal = subtotal + shippingFee;
console.log(`Subtotal: $${subtotal.toFixed(2)}, Shipping: $${shippingFee.toFixed(2)}, Total: $${finalTotal.toFixed(2)}`);
return finalTotal;
}
// Test Case: $0 discount with VIP status
calculateSmartTotal(80, 0, true);
// Output: Subtotal: $80.00, Shipping: $0.00, Total: $80.00
▶ Run Solution in Playground »