What does the caller need?
A quote needs a delivery amount to add to a subtotal. Printing that amount is insufficient: the caller needs a numeric value. Before writing the function, state its contract: valid nonnegative subtotal in, delivery charge out.
function getDeliveryCharge(subtotal) {
if (subtotal >= 100) {
return 0;
}
return 10;
}
const charge = getDeliveryCharge(80);
console.assert(charge === 10);
console.assert(getDeliveryCharge(100) === 0);
A parameter is the placeholder in the definition; an argument is the value at the call site. Return exits the current function, not the whole program. Every valid path in this function returns a number.
Guided error analysis
If the lower-subtotal path only logs 10 and has no return, the call evaluates to undefined. Adding undefined to the subtotal produces NaN. A visible console message does not supply a return value.
Calling with missing arguments supplies undefined for those parameters. That is not a valid subtotal under our contract. We will introduce explicit validation rather than relying on accidental language behavior.
Independent exercise
Write a function that returns whether a subtotal qualifies for free delivery. Then use its result to choose a human-readable message outside the function. Test 99 and 100.
Correction
function qualifiesForFreeDelivery(subtotal) {
return subtotal >= 100;
}
const eligible = qualifiesForFreeDelivery(100);
console.assert(eligible === true);
console.assert(qualifiesForFreeDelivery(99) === false);
if (eligible) console.log("Free delivery");
The function answers one Boolean question. Keeping the message outside allows another caller to use the answer without inheriting that wording. Do not return the strings "true" and "false"; both are nonempty text and truthy.
Review
Write a contract for each function: accepted inputs, output and what happens for unsupported inputs. At this point invalid inputs are outside the contract; later lessons will make failure behavior executable.