An operator is a small piece of syntax — usually a symbol like + or ===
— that combines or compares values to produce a new value. A combination of
values and operators, like price * quantity, is called an expression.
You’ve already seen a few of these in passing; this lesson lays out the full
set you’ll use daily.
These work on numbers the way you’d expect from basic math class, plus one
addition (** for exponents) that’s less common but handy:
const sum = 4 + 2; // 6
const difference = 4 - 2; // 2
const product = 4 * 2; // 8
const quotient = 4 / 2; // 2
const remainder = 7 % 2; // 1 (the remainder after dividing)
const power = 2 ** 8; // 256 (2 to the 8th power)
+ does double duty: with numbers it adds, but with strings it joins them
together — more on that in the Strings lesson.
The plain = stores a value, and you’ve already used it to declare
variables. JavaScript also offers shorthand combinations that update a
variable based on its current value — these are extremely common once you
start writing loops and counters:
let total = 10;
total += 5; // same as: total = total + 5 → 15
total -= 3; // same as: total = total - 3 → 12
total *= 2; // same as: total = total * 2 → 24
total /= 4; // same as: total = total / 4 → 6
Comparisons produce a boolean (true or false), and they’re the building
blocks of the conditionals and loops you’ll meet in upcoming lessons.
5 > 3; // true
5 < 3; // false
5 >= 5; // true
5 <= 4; // false
5 === 5; // true — strictly equal
5 === "5"; // false — different types, so not equal
5 !== "5"; // true — strictly not equal
=== and !== are the comparisons you should reach for first. They check
both the value and the type, so 5 === "5" is false because a number
and a string are never the same thing — even if they “look” similar.
These combine or invert boolean expressions, and show up constantly in
if statements:
const isAdult = true;
const hasId = false;
isAdult && hasId; // false — AND: both sides must be true
isAdult || hasId; // true — OR: at least one side must be true
!isAdult; // false — NOT: flips true to false (and back)
&& and || are also “short-circuiting” — && stops and returns the first
falsy value it finds, and || stops and returns the first truthy value
it finds, without evaluating the rest. That makes them useful for picking a
fallback value:
const displayName = user.nickname || user.name || "Anonymous";
?? and ?.Two newer operators solve a specific, common annoyance — safely handling
values that might be null or undefined.
Nullish coalescing (??) picks the right-hand value only when the
left-hand one is null or undefined — unlike ||, it won’t replace 0
or "", which are “falsy” but often perfectly valid values:
const votes = 0;
votes || 10; // 10 — 0 is falsy, so || replaces it (often not what you want)
votes ?? 10; // 0 — 0 is neither null nor undefined, so it's kept
Optional chaining (?.) lets you safely read a property that might not
exist, returning undefined instead of throwing an error:
const city = user.address?.city; // undefined if user.address doesn't exist
Older JavaScript code leans heavily on the loose equality operators, ==
and !=, instead of the strict === and !== you saw above. The loose
versions try to convert the values to a matching type before comparing them
— a process called type coercion — which can produce surprising results:
0 == ""; // true — both convert to 0
0 == "0"; // true
"" == "0"; // false — but these two also "look" comparable!
false == "0"; // true
null == undefined; // true
These inconsistencies caused enough real bugs that modern style guides and
linters recommend avoiding == and != altogether, reaching for === and
!== instead. They skip the conversion step entirely: if the types don’t
match, the values simply aren’t equal — easier to reason about and far less
surprising. You’ll still see == in older code, so it’s worth recognizing,
but there’s rarely a good reason to write it yourself today.