LearnFrenzy
Sign in Take a free test

Operators and Control Flow · Lesson 6 of 40

JavaScript Operators

4 min read Updated Nov 7, 2026 Saurabh Samir

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

Output

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);

Output

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

Output

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

Output

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);

Output

Not provided
{ retries: 0, timeout: 5000, debug: false }
Guest

The 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));

Output

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

  1. 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");

    Output

    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.

Next lesson

Search LearnFrenzy

Esc

Quick links