046: Expressions and Operators
Outcomes
By the end of this lesson, you can:
- build arithmetic and assignment expressions;
- compare values with relational operators and strict equality;
- combine Boolean rules with
&&,||, and!; - use common unary operators including
typeofand unary negation; - predict basic precedence and add parentheses for clarity; and
- identify coercion surprises without relying on them.
Prerequisites and Retrieval
Retrieve values and types from 044.
- What are the types of
"12",12, andfalse? - How do you identify an array?
- Which declaration permits reassignment?
Today's examples use only variables, values, and expressions. Conditions use these results tomorrow.
Terms
- operator: Symbol performing an operation on operands (+, &&, typeof…). — Source: MDN: Operator
- operand: A value an operator acts upon. — Source: MDN: Operator
- binary operator: An operator requiring two operands (a + b). — Source: MDN: Operator
- unary operator: An operator taking one operand (-x, !flag, typeof v). — Source: MDN: Operator
- arithmetic operator: Operators computing numeric results: + - * / % **. — Source: MDN: Arithmetic operators
- assignment operator: = and compound forms (=, +=) storing values into bindings. — Source: MDN: Assignment operators
- comparison operator: Operators comparing values: === !== < > <= >=. — Source: MDN: Comparison operators
- strict equality: === compares type and value without coercion. — Source: MDN: Strict equality
- logical operator: && || ! combine/negate conditions with short-circuit evaluation. — Source: MDN: Logical AND
- precedence: Order determining which operator binds first in mixed expressions. — Source: MDN: Operator precedence
- coercion: Automatic conversion of a value from one type to another. — Source: MDN: Type coercion
- short-circuiting: Evaluation stopping once the result is known (&&, ||). — Source: MDN: Logical AND
- Truthiness (official): "A value is truthy if it coerces to true in Boolean context; falsy values are false, 0, -0, 0n, "", null, undefined, NaN, document.all." — Source: MDN: Truthy
- Coercion (official): "Coercion is automatic conversion of a value from one type to another." — Source: MDN: Type coercion
- Nullish: "Nullish values are specifically null and undefined (used by ??)." — Source: MDN: Nullish coalescing
Beginner Explanation and Mental Model
An operator is a verb inside an expression. In price * quantity, multiplication tells JavaScript what relationship to calculate between two operands. The resulting value can be stored, logged, compared, or used by another expression.
Arithmetic
const sum = 10 + 4; // 14
const difference = 10 - 4; // 6
const product = 10 * 4; // 40
const quotient = 10 / 4; // 2.5
const remainder = 10 % 4; // 2
const power = 10 ** 2; // 100
% returns a remainder and is useful for even/odd checks. Division by zero with numbers produces Infinity, not an exception, so validate divisors in real calculations.
Assignment
= assigns; it does not ask whether values are equal:
let stock = 10;
stock = 8;
stock += 2; // equivalent to stock = stock + 2
stock -= 1;
Compound operators communicate update intent. Use them only with let or mutable properties, never to reassign a const binding.
Comparison and strict equality
>, <, >=, and <= compare order. === asks whether values have the same type and same value under strict equality rules; !== asks the opposite.
console.log(10 >= 10); // true
console.log(7 < 3); // false
console.log(5 === 5); // true
console.log("5" === 5); // false
console.log("5" !== 5); // true
Use === and !== in course code. Loose equality == and != perform type coercion and can surprise beginners: 0 == false is true. That historical syntax may appear in existing code, but do not use it as a shortcut. Convert data intentionally, then compare strictly.
Logical and unary operators
With Boolean operands, && means both rules must be true; || means at least one must be true; ! reverses truth:
const hasTicket = true;
const isOnTime = true;
const canEnter = hasTicket && isOnTime;
const needsHelp = !hasTicket;
In JavaScript, && and || actually return one of their operands, not always a Boolean. Keep beginner business rules Boolean so results remain predictable. They also short-circuit: false && secondExpression does not evaluate the second expression, and true || secondExpression does not evaluate it.
Unary typeof reports a type string, unary - negates a number, and ! converts to Boolean and reverses it. Prefer Number(text) for explicit number conversion rather than clever unary +text code.
Precedence
Multiplication and division group before addition and subtraction; comparison groups after arithmetic; && groups before ||. Do not memorize a huge table. Add parentheses to show business intent:
const total = (price * quantity) + fee;
const canBuy = isMember && (hasCredit || hasVoucher);
Worked Example: Order Calculation
const unitPrice = 250;
const quantity = 3;
const deliveryFee = 40;
const freeDeliveryMinimum = 700;
const subtotal = unitPrice * quantity;
const qualifiesForFreeDelivery = subtotal >= freeDeliveryMinimum;
const appliedDeliveryFee = qualifiesForFreeDelivery ? 0 : deliveryFee;
const total = subtotal + appliedDeliveryFee;
const isExactBudget = total === 750;
console.log("Subtotal:", subtotal);
console.log("Free delivery:", qualifiesForFreeDelivery);
console.log("Delivery fee:", appliedDeliveryFee);
console.log("Total:", total);
console.log("Exactly 750:", isExactBudget);
Expected output:
Subtotal: 750 Free delivery: true Delivery fee: 0 Total: 750 Exactly 750: true
The conditional ? : expression chooses one of two values. It is introduced fully with conditions tomorrow; here it allows the arithmetic result to feed a choice. Trace left to right by named intermediate results: calculate subtotal, compare the threshold, choose the fee, then total it. This is clearer than one dense expression.
Intermediate Example: Access Rule
const age = 19;
const hasVerifiedId = true;
const isSuspended = false;
const hasUserPass = false;
const hasGuestPass = true;
const meetsAgeRule = age >= 18;
const hasAcceptedPass = hasUserPass || hasGuestPass;
const canAccess = meetsAgeRule && hasVerifiedId && !isSuspended && hasAcceptedPass;
console.log("Age rule:", meetsAgeRule);
console.log("Accepted pass:", hasAcceptedPass);
console.log("Not suspended:", !isSuspended);
console.log("Can access:", canAccess);
Expected output is four true results. Each named Boolean answers one question. If hasUserPass is false, || still checks the guest pass. If the age rule were false, the later operands of the chained && would not be needed to determine the result.
Coercion demonstration, not advice:
console.log("10" + 2); // "102"
console.log("10" - 2); // 8
console.log("0" === 0); // false
The inconsistent-looking results come from operator-specific conversion rules. At an input boundary, write const amount = Number(inputText);, verify it is a valid number, and then do arithmetic.
Optional Advanced Extension: Nullish Defaults
?? selects the right operand only when the left is null or undefined:
const savedVolume = 0;
const defaultVolume = 50;
console.log(savedVolume || defaultVolume); // 50
console.log(savedVolume ?? defaultVolume); // 0
0 is a valid volume but is falsy, so || incorrectly replaces it. ?? preserves it. Keep ?? separate from && or || with parentheses, both for syntax requirements and clarity.
Deep Dive: Operator Families and Evaluation
Beyond arithmetic and comparisons, JavaScript includes operator families that appear frequently in production code.
Unary operators
typeof value;
!isReady;
Number("42");
delete cache.temp;
Use delete for object properties, not for removing array items.
Logical operators return operands
const displayName = user.nickname || "Guest";
const exactName = user.nickname ?? "Guest";
|| falls back for any falsy value. ?? falls back only for null or undefined.
0 || 10; // 10
0 ?? 10; // 0
Logical assignment
settings.theme ??= "system";
cache.items ||= [];
isReady &&= hasPermission;
These operators combine a logical check and assignment. Use them only when they make intent clearer.
Bitwise operators
Bitwise operators convert operands to 32-bit integers (except BigInt forms). They are useful for low-level flags but are uncommon in ordinary UI/business logic.
const READ = 1; // 001
const WRITE = 2; // 010
const DELETE = 4; // 100
const permission = READ | WRITE;
console.log((permission & WRITE) === WRITE); // true
BigInt operators
Most arithmetic and bitwise operators work with BigInt values when both operands are BigInts.
10n ** 3n; // 1000n
15n / 4n; // 3n — integer division
Precedence is not a style contest
Even when you know precedence, parentheses can communicate intent better.
const payable = subtotal + subtotal * taxRate - discount;
may be clearer as:
const tax = subtotal * taxRate;
const payable = subtotal + tax - discount;
Readable intermediate names often beat compressed expressions.
Mistakes and Debugging
- Using
=in a comparison:=assigns. Use===to compare. - Using
==to accommodate mismatched types: fix or explicitly convert the type, then use===. - Expecting
+always to add: if either operand becomes a string, it may concatenate. Log value andtypeof. - Incorrect precedence: split a long expression into named values and add parentheses.
- Reassigning a
const: compound assignment still reassigns the binding. - Expecting logical operators always to return Booleans: use Boolean operands for Boolean rules.
- Comparing
NaNwith===: useNumber.isNaN(value). - Floating-point surprise:
0.1 + 0.2is not exactly0.3in binary floating-point. Store money in smallest whole units where appropriate or use domain-safe decimal handling.
Best Practices
- Use
===and!==; avoid loose equality in application code. - Convert external strings explicitly with
Number()and validate the result. - Use named intermediate values for business rules.
- Parenthesize mixed logical conditions to make intent obvious.
- Keep operands of arithmetic operations numeric.
- Do not embed assignments inside conditions or chain assignments.
- Use
%for remainder, not percentage; calculate 15 percent asamount * 0.15. - Prefer readable expressions over operator tricks.
Tiered Exercises
Core
With const a = 17 and const b = 5, calculate all six arithmetic operations. Compare them with >, <, ===, and !==. Predict before logging.
Practice
Calculate a cart subtotal from price and quantity. A purchase is eligible for checkout only when the subtotal is at least 500, stock is available, and the account is not blocked. Log each named rule and the final result.
Professional Extension
Given const input = "25", convert it explicitly to a number. Demonstrate strict comparison before and after conversion, calculate its doubled value, and explain why using the original with + would be unsafe.
Complete Solutions
const a = 17;
const b = 5;
console.log(a + b); // 22
console.log(a - b); // 12
console.log(a * b); // 85
console.log(a / b); // 3.4
console.log(a % b); // 2
console.log(a ** b); // 1419857
console.log(a > b); // true
console.log(a < b); // false
console.log(a === b); // false
console.log(a !== b); // true
const price = 180;
const quantity = 3;
const hasStock = true;
const isBlocked = false;
const subtotal = price * quantity;
const meetsMinimum = subtotal >= 500;
const canCheckout = meetsMinimum && hasStock && !isBlocked;
console.log("Subtotal:", subtotal);
console.log("Meets minimum:", meetsMinimum);
console.log("Has stock:", hasStock);
console.log("Can checkout:", canCheckout);
Expected final result: Can checkout: true.
const input = "25";
const amount = Number(input);
console.log(input === 25); // false
console.log(amount === 25); // true
console.log(amount * 2); // 50
console.log(input + 2); // "252", demonstrating the risk
The conversion makes numeric intent explicit. Real input handling must also check Number.isNaN(amount).
Recap and Exit Questions
Operators build values from operands. Arithmetic calculates, assignment stores, comparisons produce decisions, and logical operators combine rules. Strict equality avoids implicit conversion. Precedence controls grouping, but named steps and parentheses make code clearer.
- How are
=and===different? - Why does
"5" === 5produce false? - What do
&&,||, and!mean with Booleans? - What does
%calculate? - How would you debug an unexpected
"102"result?
Official References
- MDN: Expressions and operators
- MDN: strict equality
- MDN: logical operators
- MDN: operator precedence
- ECMA-262: ECMAScript language expressions
References checked 2026-08-24.
