Lesson 2 of 5 · Client-Side Logic
Variables & Control Flow
Variables store values; if statements make decisions. These two ideas power every program ever written.
This lesson is locked. You can read ahead, but finish earlier stops to earn progress.
Listen
Watch
Read
Values before variables
JavaScript works with different kinds of values: 12 is a number, "12" is a string, true/false are booleans, and null often represents a deliberate absence. The kind matters: 12 + 3 is 15, while "12" + 3 is "123" because plus can join text.
A variable is a name attached to a value. Use const when the binding will not be reassigned and let when it will:
const studioName = 'Practice Studio'; let quantity = 2; const price = 12; quantity = 3; const total = price * quantity; console.log(total);
Trace the lines: quantity starts at 2, changes to 3, then total is computed as 12 × 3 = 36. Changing quantity later does not automatically recalculate an ordinary JavaScript total; you must run the calculation again. This becomes important when inputs change in your product.
Assignment is not comparison
= assigns a value. === compares both value and type. !== tests inequality. Greater/less comparisons such as >= return booleans. Predict these before checking in Console:
console.log(12 === '12'); console.log(12 >= 10); console.log(0 === 0);
The results are false, true, true. In if (quantity = 3) you assign 3 instead of checking it. That bug may appear to “work” while changing state unexpectedly. Use comparisons deliberately.
Read the branch as a decision
const available = 4;
const requested = 3;
if (requested <= available) {
console.log('Enough stock');
} else {
console.log('Choose fewer');
}Only one block runs. Trace with requested equal to 3, then 4, then 5. The equality boundary is intentional: asking for exactly the available amount is allowed. Test boundaries, not just a middle value.
Braces group the lines in a block. A variable declared inside a block normally belongs to that block; trying to use it outside can produce a ReferenceError. Keep a value in the scope where the code that needs it can access it, rather than declaring everything globally.
Input values begin as strings
A number input's .value is still text. Convert and validate before arithmetic. Use this small console rehearsal:
const rawQuantity = '3';
const parsedQuantity = Number(rawQuantity);
if (Number.isFinite(parsedQuantity) && parsedQuantity >= 0) {
console.log('Usable quantity:', parsedQuantity);
} else {
console.log('Enter a non-negative number');
}Number converts numeric text. Number.isFinite rejects NaN and infinities. An empty string converts to zero; decide whether your interface should treat blank as zero or require input before converting. Negative quantities should not silently become purchases. For a count of items, also consider Number.isInteger rather than accepting 1.5.
NaN means Not-a-Number. It can spread through a total if you multiply an invalid value. Detect invalid input at the point of conversion instead of replacing the final result with a mysterious zero.
Combine conditions intentionally
&& means both conditions must hold; || means at least one; ! negates a boolean. A useful range check is quantity >= 0 && quantity <= 20. Do not write 0 <= quantity <= 20: JavaScript evaluates that chain differently from ordinary mathematics.
Be careful with truthiness: if (quantity) treats numeric zero as false. Zero can be a perfectly valid quantity. Use an explicit numeric condition when zero matters. const prevents reassignment of the binding, not mutation of an object's properties; objects are taught next.
Guided rehearsal
Write a tiny stock decision using your own available count. Predict results for zero, exactly the stock count, one above and a negative value. Run one test at a time and compare output with your prediction. Then change a numeric input string to "three" and check that your validation rejects it before calculating.
Do not attach this exercise to a paid checkout or official score. It is a practice calculation; server-side rules will eventually be responsible for authoritative values.
Diagnose and prepare
| Symptom | Check |
|---|---|
| 123 instead of 15 | One operand is text; inspect with typeof and convert deliberately |
| Assignment to constant error | Do you need a reassigned let binding, or was the assignment a mistake? |
| NaN total | Inspect the input conversion before multiplying |
| Zero behaves like missing data | Replace a truthiness test with an explicit condition |
| Name is not defined | Exact spelling, declaration order and scope |
Before building the calculator, explain your inputs' types, trace one multiplication and sum, and justify the zero/empty/invalid cases. You are learning to predict behaviour—not just recognise syntax.
Key terms
- const / let
- A value that won't change / one that will.
- ===
- Exactly equal — the comparison you should always use.
- if / else
- Run different code depending on a condition.
- && and ||
- Combine conditions: and / or.
Summary — copy into your notes
- const by default, let when it changes.
- = assigns, === compares.
- if/else branches on true or false.