Operators and Control Flow · Lesson 6 of 40
JavaScript Operators
Operators combine values into new values: price * qty, age >= 18, user?.name ?? "Guest". Most work as you would expect from maths, but the logical operators do more than return true or false, and modern JavaScript adds two operators – ?. and ?? – that remove a lot of defensive code.
In this lesson
- Arithmetic, assignment and increment operators
- Comparison operators
&&,||and short-circuiting- Optional chaining
?., nullish coalescing??and precedence
Arithmetic and assignment
const price = 250, qty = 3;
console.log(price * qty, price / 4, price % 7, 2 ** 10);
let total = 0;
total += price * qty; // total = total + 750
total -= 50;
total *= 1.18; // add 18% GST
console.log(total);
let n = 5;
console.log(n++, n); // postfix: use, then increment
console.log(++n, n); // prefix: increment, then use
750 62.5 5 1024 826 5 6 7 7
Use n++ as a statement on its own line; mixing it into bigger expressions makes code hard to read.
Comparison
console.log(10 > 9, 10 >= 10, 3 !== 3);
console.log("apple" < "banana"); // strings compare by Unicode order
console.log("Zebra" < "apple"); // uppercase letters come first!
console.log("10" < "9"); // two strings: compared character by character
console.log(10 < 9);
true true false true true true false
Common mistake: comparing numbers stored as strings
"10" < "9" is true because "1" comes before "9". Convert with Number() before comparing values read from inputs, URLs or CSV files. For human-friendly text sorting use a.localeCompare(b).
Logical operators return values
&& and || don't return true/false – they return one of their operands, and stop evaluating as soon as the answer is known (short-circuiting).
What a && b and a || b return
Look at a first
- a && ba is falsy → return a (b never runs); otherwise return b
- a || ba is truthy → return a (b never runs); otherwise return b
console.log("Asha" || "Guest"); // first truthy
console.log("" || "Guest");
console.log(0 && "never"); // first falsy
console.log("ok" && "done");
const isLoggedIn = true;
isLoggedIn && console.log("Show dashboard"); // runs only if true
function expensive() { console.log("called!"); return true; }
console.log(true || expensive()); // expensive() never runs
Asha Guest 0 done Show dashboard true
Optional chaining ?.
Reading a property of undefined throws. ?. stops and returns undefined instead when the value on its left is null or undefined:
const order = { id: 7, customer: { name: "Kiran" } };
const guestOrder = { id: 8, customer: null };
console.log(order.customer?.name);
console.log(guestOrder.customer?.name);
console.log(guestOrder.customer?.address?.city);
console.log(order.items?.[0]); // with brackets
console.log(order.notify?.()); // call only if the method exists
Kiran undefined undefined undefined undefined
Nullish coalescing ?? and logical assignment
const city = guestCity() ?? "Not provided";
function guestCity() { return null; }
console.log(city);
const config = { retries: 0, timeout: null };
config.retries ??= 3; // assign only if null/undefined – keeps 0
config.timeout ??= 5000;
config.debug ||= false; // assign if falsy
console.log(config);
const name = order?.customer?.name ?? "Guest";
var order; // undefined here
console.log(name);
Not provided
{ retries: 0, timeout: 5000, debug: false }
GuestThe combination a?.b?.c ?? fallback – "read safely, then default" – is everywhere in modern code that handles API responses.
Precedence
Operators run in a fixed priority order: **, then * / %, then + -, then comparisons, then &&, then || ??, then assignment. When in doubt, add parentheses – readers will thank you.
console.log(2 + 3 * 4, (2 + 3) * 4);
console.log(true || false && false); // && first
console.log(-(2 ** 2));
14 20 true -4
JavaScript refuses to mix ?? with && or || without parentheses – a || b ?? c is a SyntaxError, written as (a || b) ?? c.
Practice
Try it yourself
Given
const res = { data: { user: { tags: [] } } }, print the first tag or "no tags" without risking an error.Show solution
const res = { data: { user: { tags: [] } } }; console.log(res?.data?.user?.tags?.[0] ?? "no tags");no tags
Quick check
What does null || "x" return? And "a" && "b"?
"x" and "b".
When does ?. stop?
When the value on its left is null or undefined; the whole chain then evaluates to undefined.
Why is count ?? 10 better than count || 10 for a count?
Because a real count of 0 is falsy; || would replace it with 10, while ?? keeps it.
Summary
&&and||short-circuit and return an operand, not always a boolean.?.reads safely;??defaults only for null/undefined;??=assigns the same way.- Compare numbers as numbers, and use parentheses when precedence is unclear.
Finished this lesson?
Mark it complete to track your progress, then carry on with the next lesson.