3.2 Parameters and Return Values
SLO 2
Describe the principles of structured programming.
Parameters and return values are how structured programming keeps a program made of separate, replaceable parts: a function takes its input through named parameters and hands its result back with return, so it can be reasoned about without reading whatever called it.
SLO 3
Describe, design, implement, and test structured programs using currently accepted methodology.
Once a function returns a value you can build a program out of small pieces and test each one on its own, which is what this section does in its closing example — three short functions, each checkable by itself, combined into one result.
Learning Objectives
By the end of this section you should be able to:
- Define a function that takes information in through parameters.
- Tell a parameter from an argument, and explain why the order matters.
- Use
returnto send a value back to the code that called the function. - Explain why
returnends the function immediately. - Distinguish a function that prints a value from one that returns it.
- Use a returned value inside a larger expression.
3.2.1 Passing Information In
Every function in Section 3.1 did exactly one fixed thing. printHeader() printed the same header every time it was called. That is useful, but limited — a function that can only ever say one sentence is not much more than a shortcut.
▶ Press Run to see the output…
What you should see:
Hello, Marisol! Hello, Marisol!
Calling it twice gets you the same greeting twice. To greet somebody else you would have to write a second function.
Instead, leave a blank in the function for the caller to fill:
▶ Press Run to see the output…
What you should see:
Hello, Marisol! Hello, Dev! Hello, Priya!
One function, three greetings. The name inside the parentheses is the blank. When you call greet("Dev"), the value "Dev" is placed into that blank, and for the length of that call, name behaves like a variable holding "Dev".
3.2.2 Parameters and Arguments
These two words get used interchangeably in conversation and mean different things precisely.
This is the moment a function stops being a shortcut and becomes a tool. A function without parameters can only repeat. A function with parameters can be applied — to this name, that number, tomorrow's data. Almost every function you will write from here on takes at least one.
A parameter is the name listed in a function's definition, inside the parentheses. It acts as a variable inside the function body and has no value until the function is called.
Definition 3.2.1 - A parameter is the name listed in a function's definition, inside the parentheses. It acts as a variable inside the function body and has no value until the function is called.
An argument is the actual value handed to a function when it is called. Each argument is assigned to the matching parameter for the duration of that call.
▶ Press Run to see the output…
What you should see:
54
A way to keep them straight: the parameter is the empty box drawn on the form, the argument is what somebody writes in it.
Definition 3.2.2 - An argument is the actual value handed to a function when it is called. Each argument is assigned to the matching parameter for the duration of that call.
Order matters
A function with several parameters matches them to arguments by position, not by name. The first argument goes to the first parameter, always.
▶ Press Run to see the output…
What you should see:
Dev is 19 years old. 19 is Dev years old.
The second call is not an error. JavaScript does exactly what it was told: name became 19 and age became "Dev". Nothing crashes; the sentence is just nonsense.
A missing argument is undefined
JavaScript does not require you to pass an argument for every parameter.
This is a whole category of bug. A function taking (width, height) called as (height, width) produces a number, not an error — the wrong number, silently. When two parameters have the same type, nothing in the language can catch the swap for you. Name them precisely, and check the order at the call site when a result is mysteriously wrong.
▶ Press Run to see the output…
What you should see:
Hello, undefined!
The parameter exists but was never given a value, so it holds undefined — the same value you met in Section 1.2. You can supply a fallback with = in the definition:
▶ Press Run to see the output…
What you should see:
Hello, friend! Hello, Priya!
The default is used only when the argument is missing.
1. In function area(w, h) called as area(3, 4), which are the arguments?
wandh3and4areaand3
Solution
b. 3 and 4 are the arguments — the actual values passed in. w and h are the parameters, the names in the definition.
2. What does this print?
▶ Press Run to see the output…
7then77then-7- An error on the second call
Solution
b. 7 then -7.
Arguments match parameters by position, so the second call sets a to 3 and b to 10. Swapping the order changes the answer without changing anything else.
Write a function introduce that takes two parameters, a name and a city, and prints "<name> is from <city>." Call it twice with different values.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
Output:
Marisol is from Chico. Dev is from Sacramento.
3.2.3 Getting a Value Back with return
Parameters send information in. return sends a value back out.
Every function so far printed its result and that was the end of it. Printing puts text on the screen, where your program cannot use it. Compare:
▶ Press Run to see the output…
What you should see:
10 I can use this: 11
Both functions computed 10. Only the second one handed it back, so the calling code could store it in result and do arithmetic with it. The first threw the number away the instant it was displayed.
The return statement ends a function immediately and sends a value back to the code that called it. That value becomes the result of the function call, and can be stored in a variable or used directly in an expression.
return is what makes a function call an expression — something with a value — rather than just an instruction. That is why a call can appear anywhere a value can:
▶ Press Run to see the output…
What you should see:
16 25 11
square(3) + square(4) works because each call becomes its number — 9 + 16.
Definition 3.2.3 - The return statement ends a function immediately and sends a value back to the code that called it. That value becomes the result of the function call, and can be stored in a variable or used directly in an expression.
▶ Press Run to see the output…
What you should see:
32 212 98.6 That is above 98 degrees Fahrenheit.
The conversion is written once and used four times, including inside a condition. A version that printed instead of returning could not have been used in that if at all.
3.2.4 return Ends the Function
return does two jobs at once: it hands back a value, and it stops the function right there. Anything after it does not run.
▶ Press Run to see the output…
What you should see:
10
That is not a limitation; it is useful. A function can return early as soon as it knows the answer:
▶ Press Run to see the output…
What you should see:
negative zero positive
There is no else anywhere, and none is needed. Once a return runs, the function is finished — so reaching the line after an if already tells you that if was false.
1. What does this return when called with 3?
▶ Press Run to see the output…
bigsmallbigthensmall
Solution
a. big. The first return ends the function, so the second one is never reached. A function returns exactly one value per call, however many return statements it contains.
Write a function isEven that takes a number and returns true when it is even and false otherwise. Print the result for 4 and for 7. (Hint: the remainder operator % from Section 2.4.)
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
Output:
true false
Once you are comfortable, notice that n % 2 === 0 is already true or false, so the whole body can be return n % 2 === 0;. The if was never doing any work.
3.2.5 Printing Is Not Returning
This is the single most common misunderstanding about functions, and it is worth slowing down for.
console.log shows a value to a human. return gives a value to the program. They are not alternatives — they do unrelated things.
▶ Press Run to see the output…
What you should see:
5 total is: undefined
Read that output carefully. The 5 appeared — the function did its arithmetic correctly. But total is undefined, because addAndPrint never returned anything. The number was displayed and then discarded.
A function that finishes without executing a return statement produces the value undefined. The function still ran; it simply handed nothing back.
The fix is one word:
▶ Press Run to see the output…
What you should see:
total is: 5 and doubled: 10
undefined in the wrong place
If a variable holding a function's result prints as undefined even though the function clearly worked, look for a missing return. Beginners often add a second console.log to "check the value", see the right number printed from inside the function, and conclude the function is fine — but that print is coming from inside, and proves nothing about what came out.
Definition 3.2.4 - A function that finishes without executing a return statement produces the value undefined. The function still ran; it simply handed nothing back.
Which should a function do?
As a rule, a function should return its result and let the caller decide whether to print it. A function that prints can only ever be used one way. A function that returns can be printed, stored, compared, added, or passed on.
▶ Press Run to see the output…
What you should see:
12 Free shipping!
1. What does this print?
▶ Press Run to see the output…
6then66thenundefinedundefinedthen6
Solution
b. 6 then undefined.
The 6 comes from the console.log inside triple. Then x prints as undefined, because triple has no return and so handed nothing back.
2. A function computes a value correctly, but the variable holding its result is undefined. What is the most likely cause?
- The function was called with the wrong arguments.
- The function prints its result instead of returning it.
- The variable was declared with
const.
Solution
b. A missing return. The computation ran — that is why you saw the right value printed — but nothing was handed back to the caller.
The function below is meant to give the caller a usable value but does not. It prints 12 and then Two rooms: NaN.
function area(width, height) {
console.log(width * height);
}
const a = area(3, 4);
console.log("Two rooms: " + (a * 2));
Write the fixed version in the editor, and prove the fix by using the result in an expression.
▶ Press Run to see the output…
Solution
Swap console.log for return, and let the caller print.
▶ Press Run to see the output…
Output:
One room: 12 Two rooms: 24
Before the fix, a was undefined and a * 2 was NaN.
3.2.6 Building With Returned Values
Because a call to a returning function is a value, calls can be fed straight into other calls. This is how small functions build up to big programs.
▶ Press Run to see the output…
What you should see:
30 20
The inner call runs first. addTen(5) becomes 15, then double(15) becomes 30. Reversing the order gives a different answer, which is worth checking whenever nested calls surprise you.
▶ Press Run to see the output…
What you should see:
Subtotal: $13.50 Total: $14.58 One line: $14.58
Each function does one small thing and hands the result on. The last line does the whole job in one expression, and gets the same answer — because each call is just its value.
toFixed(2) rounds a number to two decimal places and gives back a string, which is what you want for money.
Notice how none of the three functions prints anything. That is what let the last line exist. Had subtotal printed instead of returned, there would have been nothing to hand to withTax, and the chain would have collapsed. Functions that return compose; functions that print do not.
Write two functions: perimeter(w, h) returning 2 * (w + h), and sizeLabel(n) returning "small" when n is under 20 and "large" otherwise. Then print the label for a 3 by 4 rectangle's perimeter in one expression.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
Output:
14 small
perimeter(3, 4) becomes 14, and sizeLabel(14) becomes "small".
Problem Set 3.2
3.2.1 In function area(w, h) called as area(3, 4), which are the arguments and which are the parameters?
Solution
Step 1 — Look at where each name appears:
function area(w, h) is the definition. The names w and h are written into the definition, so they are the parameters — placeholders that have no value until someone calls the function.
Step 2 — Look at the call:
area(3, 4) is the call. The values 3 and 4 are handed over at the moment of calling, so they are the arguments.
Step 3 — Match them up by position:
Position decides the pairing, not the names. The first argument 3 goes into the first parameter w; the second argument 4 goes into the second parameter h.
Answer: w and h are the parameters (they live in the definition); 3 and 4 are the arguments (they are the values passed in the call). w becomes 3 and h becomes 4.
3.2.2 What does this print?
▶ Press Run to see the output…
Solution
Step 1 — Read what the function does:
subtract(a, b) prints a - b. It does not return anything; it prints, so each call puts one line on the console.
Step 2 — Work through the first call:
subtract(10, 3) assigns a = 10 and b = 3, so it prints 10 - 3, which is 7.
Step 3 — Work through the second call:
subtract(3, 10) assigns a = 3 and b = 10, so it prints 3 - 10, which is -7. Same function, same arguments, different order — and subtraction is not symmetric, so the answer changes sign.
Answer: Two lines: 7 then -7. The order of the arguments decides which value lands in a and which in b, and swapping them flips the result.
3.2.3 What does test(3) return, and why is the second return never reached?
▶ Press Run to see the output…
Solution
Step 1 — Follow the call with n = 3:
test(3) starts the function body with n set to 3. The first statement is if (n > 0), and 3 > 0 is true, so the block runs.
Step 2 — Hit the first return:
Inside the block is return "big";. A return does two things at once: it hands the value back to the caller, and it ends the function immediately.
Step 3 — See why the second return is unreachable on this call:
Because the function has already ended, return "small"; on the last line is never executed. It is not skipped by a condition; the function simply stopped before reaching it. That last line only runs when the if condition is false — for example test(-2), which returns "small".
Answer: test(3) returns "big", so console.log(test(3)) prints big. The second return is never reached because the first return ended the function on the spot; it is the fallback for calls where n > 0 is false.
3.2.4 What does this print, and where does each of the two lines come from?
▶ Press Run to see the output…
Solution
Step 1 — Trace the call itself:
triple(2) runs the body with n = 2. The body is console.log(n 3), so it prints 6. That is the first line, and it comes from inside* the function.
Step 2 — Ask what the call produced:
The function printed, but it never used return. A function that finishes without executing a return produces undefined. So const x = triple(2) stores undefined in x.
Step 3 — Trace the second print:
console.log(x) prints the contents of x, which is undefined. That is the second line, and it comes from outside the function.
Answer: Two lines: 6 then undefined. The 6 is printed by the console.log inside triple; the undefined is printed by the console.log outside it, because triple prints rather than returns and so hands back nothing.
3.2.5 A function computes the right value, but the variable holding its result is undefined. What is the most likely cause?
Solution
Step 1 — Separate the two things a function can do with a value: Printing shows a value to a human reading the console. Returning hands the value back to the program. They look the same when you run the code, because both put something on screen — but only one of them leaves a value behind.
Step 2 — Match that to the symptom:
The computation is right, so the arithmetic inside the function is fine. What is missing is the handover. If the function ends with console.log(result) instead of return result, it finishes without executing any return, and the call produces undefined — which is exactly what the variable holds.
Step 3 — Name the fix:
Change the last line of the function from console.log(result) to return result. If the printout is still wanted, the caller can print the returned value.
Answer: The function prints its result instead of returning it — it ends with console.log(...) and no return, so the call produces undefined and that is what the variable receives. Replace the final console.log with return.
3.2.6 Write a function introduce(name, city) that prints "<name> is from <city>." and call it twice.
Solution
Step 1 — Decide what the function needs to be told:
The sentence changes in two places — the person and the place — so the function needs two parameters, name and city, in that order.
Step 2 — Build the sentence:
Joining strings with + glues them end to end, so the spaces and the final period have to be written explicitly inside the quoted pieces: name + " is from " + city + ".".
Step 3 — Write it and call it twice:
▶ Press Run to see the output…
Step 4 — Check it:
The first call sets name = "Marisol" and city = "Fresno", printing Marisol is from Fresno. The second call reuses the same body with new arguments, printing Dae-ho is from Seoul. One definition, two results — which is the whole point of parameters.
Answer: The program above. introduce takes name and city, prints "<name> is from <city>.", and the two calls print Marisol is from Fresno. and Dae-ho is from Seoul.
3.2.7 Write a function isEven(n) that returns true or false, then rewrite its body as a single line with no if.
Solution
Step 1 — Write the version with if:
A number is even when the remainder after dividing by 2 is 0. % gives that remainder, and === tests equality.
▶ Press Run to see the output…
Step 2 — Notice what the if is actually doing:
The condition n % 2 === 0 is already true or false. The if takes that boolean, and then hands back the very same boolean. That is a round trip with no work in the middle.
Step 3 — Return the condition directly:
▶ Press Run to see the output…
Step 4 — Check it:
isEven(4) evaluates 4 % 2 === 0 → 0 === 0 → true. isEven(7) evaluates 7 % 2 === 0 → 1 === 0 → false. Both versions print true then false.
Answer: The one-line body is return n % 2 === 0;. The if was unnecessary because the comparison already produces the boolean the function was returning.
3.2.8 Fix this function so the caller can use the result, and prove it by doubling the value.
▶ Press Run to see the output…
Solution
Step 1 — Find the defect:
area computes width height correctly but hands it to console.log. The function ends without a return, so the call produces undefined, a is undefined, and a 2 is NaN.
Step 2 — Return instead of print:
Swap console.log(width height) for return width height. Now the value goes back to the caller instead of onto the screen.
Step 3 — Write the fixed program:
▶ Press Run to see the output…
Step 4 — Prove it by doubling:
area(3, 4) returns 12, so a holds 12, a * 2 is 24, and the console shows Two rooms: 24. The doubling is the proof: an arithmetic operation on the result only works if a real number came back.
Answer: Change the function body to return width * height;. The program then prints Two rooms: 24.
3.2.9 What does greet() print, given the definition below, and why?
▶ Press Run to see the output…
Solution
Step 1 — Count the parameters against the arguments:
greet is defined with one parameter, name. The call greet() supplies zero arguments.
Step 2 — Ask what the unmatched parameter holds:
JavaScript does not object to a missing argument. It runs the function anyway and leaves the unmatched parameter set to undefined — the value that means "nothing was ever put here."
Step 3 — Build the string with that value:
The body is "Hello, " + name + "!". With name equal to undefined, string concatenation converts it to the text "undefined", giving "Hello, undefined!".
Answer: It prints Hello, undefined!. The call supplied no argument, so the parameter name was left as undefined, and joining that to a string turned it into the literal word undefined in the output.
3.2.10 Rewrite the function in 3.2.9 so that calling greet() with no argument prints "Hello, friend!".
Solution
Step 1 — Decide where the fallback belongs: The caller is the one omitting the argument, so the fallback has to live in the definition — that is the only place that runs when nothing is passed.
Step 2 — Write a default parameter:
Assigning to a parameter in the definition, name = "friend", sets the value used only when that argument is missing.
▶ Press Run to see the output…
Step 3 — Check both paths:
greet() passes nothing, so name falls back to "friend" and the console shows Hello, friend!. greet("Marisol") passes an argument, so the default is ignored and it shows Hello, Marisol!.
Answer: Give the parameter a default: function greet(name = "friend"). greet() now prints Hello, friend! while greet("Marisol") still prints Hello, Marisol!.
3.2.11 Write a function largest(a, b, c) that returns the largest of three numbers, using early return and no else.
Solution
Step 1 — Plan the comparisons:
With three values, one is largest when it is at least as big as both of the others. That gives three tests: a against b and c, then b against c, and whatever is left is c.
Step 2 — Use early return instead of else:
Because return ends the function immediately, reaching the second test already proves the first one failed. There is nothing for an else to add — the earlier return has already carried that information.
▶ Press Run to see the output…
Step 3 — Check all three exits:
largest(3, 9, 4) fails the first test, passes 9 >= 4, returns 9. largest(8, 2, 5) passes the first test and returns 8. largest(1, 6, 7) fails both tests and falls through to return c, giving 7. The console shows 9, 8, 7.
Answer: The function above. Each return ends the function, so a failed test is enough to move on — no else is needed, and the final return c handles the only case left.
3.2.12 Given double(n) returning n * 2 and addTen(n) returning n + 10, what do double(addTen(5)) and addTen(double(5)) produce, and why do they differ?
Solution
Step 1 — Work from the inside out: When one call sits inside another, the inner one runs first and its returned value becomes the argument to the outer one.
Step 2 — Evaluate double(addTen(5)):
The inner call addTen(5) returns 5 + 10, which is 15. That 15 is then handed to double, giving 15 * 2, which is 30.
Step 3 — Evaluate addTen(double(5)):
Now double(5) runs first, returning 5 * 2, which is 10. That 10 goes to addTen, giving 10 + 10, which is 20.
Step 4 — Say why they differ:
Doubling and adding ten are not interchangeable. Doubling last multiplies the added ten as well; doubling first leaves the ten untouched. 2(n + 10) is 2n + 20, while 2n + 10 is ten smaller — and 30 - 20 = 10 is exactly that gap.
Answer: double(addTen(5)) produces 30 and addTen(double(5)) produces 20. The inner call always runs first, so the order decides whether the + 10 gets doubled along with the number.
3.2.13 Write a function initials(first, last) that returns a string like "M.R." from "Marisol" and "Rivera". (Hint: first[0] gives the first character.)
Solution
Step 1 — Pull out the first character of each name:
The hint gives the tool: first[0] is the first character of first, so "Marisol"[0] is "M" and "Rivera"[0] is "R".
Step 2 — Assemble the string:
The target "M.R." is first initial, period, second initial, period — so join four pieces: first[0] + "." + last[0] + ".".
Step 3 — Return it, do not print it:
The problem says returns, so the body ends with return. That keeps the result usable in a variable or a longer expression.
▶ Press Run to see the output…
Step 4 — Check it:
The first call returns "M.R." and prints it. The second call proves the value is usable inside a larger expression: it prints Signed: D.K. — something a printing version of this function could not do.
Answer: The function above, whose body is return first[0] + "." + last[0] + ".";. initials("Marisol", "Rivera") returns "M.R.".
3.2.14 Explain in one sentence why a function that prints its result cannot be used inside a larger expression.
Solution
Step 1 — Ask what an expression needs: An expression is built by combining values. Every piece of it has to be a value — something the surrounding arithmetic or concatenation can operate on.
Step 2 — Ask what a printing function supplies:
A function that prints sends its result to the console and then finishes without a return, so the call itself produces undefined. The screen got the number; the expression got nothing usable.
Answer: A function that prints its result hands back undefined rather than the value, so using the call inside a larger expression operates on undefined — producing NaN or the literal text undefined instead of the intended result.
Key Terms
Parameter -- A name listed in a function's definition, acting as a variable inside the function body; it has no value until the function is called.
Argument -- The actual value handed to a function when it is called, assigned to the matching parameter by position.
return -- A statement that ends a function immediately and sends a value back to the caller.
Return value -- The value a function call produces, usable in a variable, an expression, or another call.
Early return -- Returning as soon as the answer is known, which removes the need for else branches.
Default parameter -- A fallback value written as name = "friend" in the definition, used only when that argument is missing.
undefined -- What a function call produces when the function finished without executing a return.
Composition -- Using the value returned by one function directly as the argument to another, as in double(addTen(5)).