JavaScript / Basic: values and browser foundations / Lesson 2
Coercion, comparisons, and controlled decisions
Make decisions predictable by separating conversion, truthiness, and equality. A workshop form shows why valid zero values and missing values need different treatment.
On this page
Lesson goals
- Choose explicit conversion and comparison rules.
- Preserve meaningful falsy values.
- Trace branches and loops with invariants.
Operators choose conversion rules
The plus operator can add numbers or concatenate strings, depending on its operands after primitive conversion. Other numeric operators have different conversion behavior. Do not learn this by assuming that all operators interpret a numeric-looking string identically. Parse user input once at a named boundary and keep the resulting domain value numeric. Distinguish Number from parseInt: Number requires the whole string to represent a number, while parseInt can accept an initial integer portion. Neither alone establishes a business rule. A form accepting whole seat counts should reject a decimal or trailing junk deliberately.
console.log("2" + 1);
console.log(Number("2") + 1);
console.log(Number("2 seats"));
console.log(parseInt("2 seats", 10));
21
3
NaN
2
Only the explicit whole-value conversion rejects the trailing words here. A valid quantity still needs integer and range checks.
Equality and ordering answer different questions
Strict equality avoids the cross-type coercion performed by loose equality, making most application comparisons easier to review. Compare normalized values of the intended type, rather than sprinkling conversions through conditions. NaN is not strictly equal to itself; Number.isNaN checks specifically for that numeric value without converting its argument. Object equality compares identity, not structural similarity. Two separately created objects with identical fields are different objects. For sorted user-facing names, choose an appropriate locale-aware comparison instead of assuming numeric ordering rules apply to text. State the comparison contract before implementing a branch.
Missing is not the same as zero
A condition converts its value to Boolean. Zero, the empty string, null, undefined, NaN, and false are falsy; arrays and objects are truthy even when empty. The OR operator returns an operand and therefore replaces valid zero or empty-string values with its fallback. Nullish coalescing replaces only null and undefined. Choose based on meaning: an optional discount of zero must remain zero, whereas a blank search string may intentionally mean no filter. An explicit validation branch is preferable when null is an error rather than an invitation to use a default.
const options = { discount: 0 };
console.log(options.discount || 10);
console.log(options.discount ?? 10);
console.log([] ? "truthy" : "falsy");
10
0
truthy
The first result is a potentially wrong business default. The second preserves zero; the third shows why array emptiness needs a length check.
Write branches around domain facts
For an age rule of sixteen through sixty-five inclusive, first establish that the value is a finite integer, then check both bounds. Keep invalid input distinct from a valid age outside eligibility. An if/else chain communicates mutually exclusive outcomes; independent if statements can both run when conditions overlap. A switch is useful for a closed set of action names, but an unrecognized action still needs a deliberate default path. Avoid deeply nested expressions that hide whether a rejected operation already changed state. Compute a decision first, then apply the intended effect.
Bound repetition and expose progress
A loop needs an initial state, a continuation condition, and progress toward stopping. For a small invoice list, keep an accumulator in integer cents and explain the invariant after each item: it equals the total of processed items. Use for...of when values matter and a numeric index when positions are part of the problem. Do not mutate a collection during traversal without understanding how that changes later visits. For user-controlled sizes, impose sensible bounds and consider responsiveness. A correct loop that monopolizes a browser thread can still make the page unusable.
Common errors and fixes
A quantity is concatenated instead of added
- Why it happens
- Text input crosses into numeric logic unchanged.
- How to fix it
- Parse and validate once before arithmetic.
- Prevent it next time
- Test both value and type at the input boundary.
Zero discount is replaced with ten
- Why it happens
- OR is used for a missing-only default.
- How to fix it
- Use ?? when only nullish values should fall back.
- Prevent it next time
- Include valid falsy examples in acceptance tests.
A loop never finishes
- Why it happens
- The progress variable does not reach the stopping condition.
- How to fix it
- Trace a short input and correct the update or bound.
- Prevent it next time
- State a termination argument and cap external sizes.
Check your understanding
1. An optional result count may be zero. Choose a default operation.
Show worked solution
Use count ?? 20 if null and undefined mean unspecified and zero is valid. Validate a provided count independently; a string or negative number should not be accepted merely because it is non-nullish. A default does not replace a schema rule.
2. What should happen to "3x" in a whole-number seat form?
Show worked solution
Reject it rather than partially parsing three. Check trimmed nonempty text, convert with Number, and require a finite integer within the permitted range. Report the invalid-input outcome before any reservation is created, preserving the original text for correction.
Key takeaways
- Normalize types before comparison and arithmetic.
- Defaults, validation, and truthiness have distinct purposes.