Operators and Expressions
Why this matters: Operators are how you do anything: add two numbers, compare values, decide between two options. Most of programming is "if this is true, do that". Operators are the building blocks of "this is true". Get fluent with them and JavaScript starts to feel comfortable.
Arithmetic operators
The maths you would expect, plus one or two extras.
const a = 10;
const b = 3;
a + b; // 13 (addition)
a - b; // 7 (subtraction)
a * b; // 30 (multiplication)
a / b; // 3.333.. (division)
a % b; // 1 (remainder, also called modulus)
a ** b; // 1000 (exponentiation: a to the power of b)
The % and ** operators are the ones beginners often have not seen before. They both come up a lot.
JavaScript also has increment and decrement operators:
let count = 5;
count++; // count is now 6
count--; // count is now 5 again
Assignment operators (shorthand)
Anything you do to a variable and assign back to itself has a shorthand:
let x = 10;
x += 5; // same as x = x + 5 (15)
x -= 3; // same as x = x - 3 (12)
x *= 2; // same as x = x * 2 (24)
x /= 4; // same as x = x / 4 (6)
You will read these all the time in other people's code.
Comparison operators (and the most important quirk in JS)
Comparing values returns a boolean (true or false).
const age = 18;
age === 18; // true
age !== 20; // true
age > 15; // true
age < 21; // true
age >= 18; // true
age <= 17; // false
Now for the most important quirk in JavaScript:
age === "18"; // false (different types: number and string)
age == "18"; // true (JavaScript silently converts the string to a number)
JavaScript has two equality operators:
===(strict equality): values must be equal and of the same type==(loose equality): JavaScript tries to convert the types until they match, then compares
Always use ===. Loose equality (==) is the source of many famous JavaScript bugs and surprising behaviour. Every senior JS developer will tell you the same thing: pretend == does not exist.
Logical operators
The three ways to combine boolean values.
const age = 20;
const hasID = true;
const day = "Saturday";
// AND (&&): both sides must be true
const canVote = age >= 18 && hasID; // true
// OR (||): at least one side must be true
const isWeekend = day === "Saturday" || day === "Sunday"; // true
// NOT (!): flips the boolean
const isMinor = !canVote; // false
Ternary operator (the inline if-else)
When you need to pick between two values based on a condition, the ternary operator is a one-liner alternative to a full if statement:
const age = 17;
const status = age >= 18 ? "Adult" : "Minor";
// status is now "Minor"
Real-world example: tiered discounts.
const price = 1500;
const discount = price > 1000 ? 0.1 : 0.05;
const finalPrice = price * (1 - discount);
console.log(`Final price: R${finalPrice}`); // R1350
Modern operators: ?? and ?.
These two operators arrived recently (2020) and they make a real difference. Worth learning early.
Nullish coalescing (??)
?? returns the right-hand value if the left is null or undefined, otherwise the left.
const userName = null;
const name = userName ?? "Guest"; // "Guest"
const score = 0;
const display = score ?? 100; // 0 (because 0 is not null/undefined)
The key difference from ||: ?? only kicks in for null or undefined. The || operator falls back for any falsy value (including 0, "" or false), which causes bugs.
Optional chaining (?.)
?. lets you reach into objects without crashing if a path is missing.
const user = {
name: "Sipho",
address: { city: "Johannesburg" },
};
user.address.city; // "Johannesburg"
user.contact.email; // TypeError: Cannot read properties of undefined
user.contact?.email; // undefined (no crash)
user.address?.city; // "Johannesburg"
?. is one of the most useful additions to JavaScript in the last decade. Use it whenever you read a value from an object that might not have it.
Worked example: a shopping cart
A small program that uses arithmetic, comparison, logical and ternary operators together:
const itemPrice = 299.99;
const quantity = 3;
const shippingCost = 50;
const hasCoupon = true;
const subtotal = itemPrice * quantity;
// 10% off if subtotal is over R500 AND the user has a coupon
const qualifiesForDiscount = subtotal > 500 && hasCoupon;
const discount = qualifiesForDiscount ? subtotal * 0.1 : 0;
// Free shipping over R750
const shipping = subtotal >= 750 ? 0 : shippingCost;
const total = subtotal - discount + shipping;
console.log(`Subtotal: R${subtotal.toFixed(2)}`);
console.log(`Discount: R${discount.toFixed(2)}`);
console.log(`Shipping: R${shipping.toFixed(2)}`);
console.log(`Total: R${total.toFixed(2)}`);
Run this and try changing the values. Make the quantity 1 and watch the discount disappear. Set hasCoupon to false and watch the same.
Best practices
A short list of things worth doing from day one:
- Always use
===, never== - Use template literals with backtick strings instead of the old
"text " + variableconcatenation - Use parentheses for clarity when an expression mixes several operators
- Use
?.and??instead of long&&chains for "this might be missing" checks
What's next
You now have the building blocks: variables, types and operators. The next lesson is type conversion and coercion, which covers what happens when JavaScript silently changes types behind your back and how to be deliberate about it.