← Back to JavaScript series
βž—
Basics
Basics Β· Prerequisite: 02_Variables_and_Types

03. Operators and Expressions

Beyond the four basic operators you also have remainder `%`, exponentiation `**`, and increment/decrement `++`/`--`. Compound assignment operators like `+=`, `-=` are short and very common.

operatorsexpressionsshort-circuitoptional chaining
Duration
⏱ ~1 hour
Level
πŸ“Š Beginner
Prerequisite
🎯 Lecture 2
OUTCOME
Beyond the four basic operators you also have remainder `%`, exponentiation `**`, and increment/decrement `++`/`--`. Compound assignment operators like `+=`, `-=` are short and very common.

What you'll learn

  • 1Use arithmetic, assignment, comparison, and logical operators appropriately.
  • 2Understand the difference between `==` and `===` and default to `===`.
  • 3Use short-circuit evaluation and nullish coalescing (`??`).
  • 4Use optional chaining (`?.`) to access properties safely.
  • 5Explain the difference between an expression and a statement.

Overview

Beyond the four basic operators you also have remainder `%`, exponentiation `**`, and increment/decrement `++`/`--`. Compound assignment operators like `+=`, `-=` are short and very common.

Core Concepts

1. Arithmetic and assignment

Beyond the four basic operators you also have remainder `%`, exponentiation `**`, and increment/decrement `++`/`--`. Compound assignment operators like `+=`, `-=` are short and very common.

javascript
let n = 10;
n **= 2;   // 100
n %= 7;    // 100 % 7 = 2

2. Comparison operators

`==` converts types before comparing; `===` checks both value and type. Use `===` in almost every case.

javascript
0 == "";     // true
0 === "";    // false
NaN === NaN; // false  β†’ use Number.isNaN

3. Logical operators and short-circuit

`&&` and `||` don't return booleans β€” they return one of the original operands. `??` only falls through to the right when the left is `null` or `undefined`.

javascript
const name = userName || "anonymous";  // fallback when userName is falsy
const port = process.env.PORT ?? 3000; // fallback only on null/undefined

4. Optional chaining

`?.` stops evaluating as soon as the left side is `null` or `undefined`, returning `undefined`. Great for digging into deeply nested objects safely.

javascript
const city = user?.address?.city ?? "unknown";
fn?.();         // call fn only if it exists
arr?.[0];       // first element only if arr exists

Examples

FileWhat it covers
`01_arithmetic.js`Arithmetic and assignment, exponentiation, remainder
`02_comparison.js``==` vs `===` and comparing NaN
`03_logical.js``&&`, `||`, `??`
`04_optional_chaining.js`Safe property access with `?.`

src/01_arithmetic.js

javascript
/** Walk through arithmetic and compound-assignment operators. */
const a = 17;
const b = 5;

console.log("a + b =", a + b);
console.log("a - b =", a - b);
console.log("a * b =", a * b);
console.log("a / b =", a / b);
console.log("a % b =", a % b);
console.log("a ** b =", a ** b);

let n = 10;
n += 5;  console.log("n += 5 β†’", n);
n *= 2;  console.log("n *= 2 β†’", n);
n **= 2; console.log("n **= 2 β†’", n);

src/02_comparison.js

javascript
/** Show the difference between == and === and how NaN compares. */
console.log(0 == "");        // true
console.log(0 === "");       // false
console.log(null == undefined);  // true
console.log(null === undefined); // false

console.log(NaN === NaN);             // false
console.log(Number.isNaN(NaN));       // true
console.log(Object.is(NaN, NaN));     // true

src/03_logical.js

javascript
/** Compare the short-circuit behavior of &&, ||, and ??. */
const empty = "";
const zero = 0;

console.log(empty || "fallback");   // "fallback" (empty is falsy)
console.log(empty ?? "fallback");   // ""         (not null/undefined)
console.log(zero || 100);            // 100
console.log(zero ?? 100);            // 0

// && returns the first falsy operand, or the last value
console.log(true && "ok");           // "ok"
console.log(0 && "skip");            // 0

src/04_optional_chaining.js

javascript
/** Optional chaining for safe property access. */
const user = {
  name: "Ada",
  address: { city: "London" },
};

console.log(user?.address?.city);                 // "London"
console.log(user?.company?.name);                 // undefined
console.log(user?.company?.name ?? "unemployed"); // "unemployed"

const maybeFn = undefined;
console.log(maybeFn?.());                  // undefined (no error)

const arr = null;
console.log(arr?.[0]);                     // undefined

Common Mistakes

  1. Reaching for `||` in the `0 || default` pattern when you actually want `??` (because `0` should be a valid value).
  2. Assuming floating-point arithmetic is exact (`0.1 + 0.2 !== 0.3`).
  3. Forgetting that `NaN === NaN` is false and trying to compare with `=== NaN`.
  4. Subtle bugs caused by the difference between `++x` and `x++`.
  5. Making only the first step optional in `a?.b.c` and leaving the rest unguarded.

FAQ

Q1. Should I never use `==`?

The idiom `x == null` (catches both null and undefined) is fine, but otherwise stick to `===`.

Q2. Which should be my default, `??` or `||`?

If you mean "fall back when the value is missing", `??` is safer because it treats `0` and `""` as valid values.

Q3. What's the difference between an expression and a statement?

An expression evaluates to a value. A statement performs an action. `if (...)` is a statement; `a ? b : c` is an expression.

Practice

  • `homework_01.js` β€” Print the sum, difference, quotient, remainder, and power of two numbers in a table.
  • `homework_02.js` β€” Pull a safe value out of a nested object with `?.` and `??`.

homework/README.md

## homework_01.js

  • Define two numbers `a` and `b` as constants and print +, -, *, /, %, ** via `console.table`.

## homework_02.js

  • Use optional chaining to safely read `order.customer.address.city`.
  • Fall back to "No address provided" when it's missing.
  • Test with objects that are missing some of those properties.

homework/answer/homework_01.js

javascript
/** Print the arithmetic results of two numbers as a table. */
const a = 13;
const b = 4;

const result = {
  "+": a + b,
  "-": a - b,
  "*": a * b,
  "/": a / b,
  "%": a % b,
  "**": a ** b,
};

console.table(result);

homework/answer/homework_02.js

javascript
/** Safe lookup with optional chaining + nullish coalescing. */
const orders = [
  { id: 1, customer: { name: "A", address: { city: "Seoul" } } },
  { id: 2, customer: { name: "B" } },
  { id: 3 },
];

for (const order of orders) {
  const city = order?.customer?.address?.city ?? "No address provided";
  console.log(`Order ${order.id}: ${city}`);
}

Next Lecture

[04_Control_Flow](../04_μ œμ–΄λ¬Έ/) β€” Direct your program's flow with conditions and loops.

Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub β†—