A variable binding gives a value a name. Prefer const when you will not reassign that binding and let when you will. const does not freeze an object: a constant binding can still refer to an array whose contents change. Blocks introduce scope for let and const; reading a binding before its declaration runs throws an error. Avoid var while learning new code because its function-level scope introduces a different set of rules.
JavaScript has seven primitive types: string, number, bigint, boolean, undefined, symbol and null. Objects, arrays and functions are objects rather than additional primitive categories. typeof null returns "object" for historical reasons, so check null explicitly when validating objects.
Convert deliberately
A form field supplies text even when the user types digits. Convert at the boundary, reject invalid values, and keep arithmetic numeric afterward. Do not assume parseInt validates a complete string: it accepts a numeric prefix. Also notice that Number("") is zero; rejecting blank input before conversion matters.
function parseMinutes(raw) {
if (typeof raw !== "string" || raw.trim() === "") {
throw new Error("Enter a duration.");
}
const value = Number(raw);
if (!Number.isInteger(value) || value < 1 || value > 180) {
throw new Error("Use whole minutes from 1 to 180.");
}
return value;
}
let total = 0;
for (const raw of ["25", "15", "40"]) {
const minutes = parseMinutes(raw);
if (minutes >= 20) total += minutes;
}
console.log(total);
console.log(0 === false, "5" === 5);
console.log(0 ?? 30, 0 || 30);
The output is 65, then false false, then 0 30. Strict equality === does not convert the operands to make them match. Nullish coalescing ?? substitutes a default only for null or undefined, while || substitutes for any falsy value, including zero, false and the empty string. Choose based on the meaning of missing input.
Follow execution one branch at a time
Use if for conditional work and switch for clearly named alternatives. A traditional switch case falls through unless it exits, for example with break or return. Use for...of to visit iterable values such as array items; for...in visits enumerable property names and is usually the wrong choice for an array's values.
A while loop must make progress toward stopping. break exits the nearest loop, and continue skips the remainder of its current iteration. Empty arrays and empty objects are truthy; an array's existence does not mean it has items. Check items.length when that is the actual question.
JavaScript numbers use floating-point representation. Decimal sums may be inexact; Number.isSafeInteger checks whether an integer fits the reliably represented range. For simple currency exercises, store a bounded count of minor units such as paise. Real monetary systems also need explicit rounding and domain rules. BigInt represents integers beyond the ordinary safe range, but cannot be freely mixed with numbers or directly serialized by ordinary JSON.stringify.
Exercise: test parseMinutes with blank text, "12x", "0", "181" and "12.5". Then accept surrounding whitespace without accepting invalid suffixes.
Solution guidance: the existing conversion accepts " 25 " and rejects every listed invalid input. Keep the whole-string conversion and integer/range checks. Do not replace them with a truthiness check: that does not express the allowed domain.
Reference: Grammar and types.
Previous: JavaScript: Setup and Runtime. Next: Functions, Scope and Closures.

