These questions ask you to classify function forms, trace arguments into parameters, and determine what a call returns. Some also test the difference between expression-bodied arrows, block-bodied arrows, and captured lexical bindings.
Trace a call in three passes
First identify the function value. A declaration such as function greet(name) introduces a named callable with a parameter list. A function expression also produces a callable value, which may be assigned, stored, or passed elsewhere; it need not be anonymous. Creating either function is different from calling it.
| Pass | Decision rule |
|---|---|
| Bind arguments | Match supplied values to named parameters by position. Too few arguments are allowed and leave unmatched parameters as undefined unless a default applies. Extra arguments do not stop an ordinary call. |
| Apply special parameters | A default runs for a missing argument or an explicit undefined, but not for null. A final rest parameter gathers the remaining values into an Array. At a call site, spread does the reverse job by expanding iterable values into separate arguments. |
| Find the result | An executed return ends the current call and sends its expression value to the caller. Reaching the end without such a value produces undefined. |
| Classify an arrow body | A single expression after the arrow is returned implicitly. For example, an expression-bodied square arrow can evaluate x times x and return that product. A block body needs an executed return; an object literal used as an implicit expression must be parenthesized. |
| Resolve a captured name | A function resolves captured names through the lexical environment where it was created, not through the unrelated locals of a later caller. That environment can remain available for as long as the function needs it. |
Where the mistakes come from
| Tempting route | How to reject it |
|---|---|
| Confusing a function definition with an immediate call or with a stored result | A declaration or expression creates a callable value. Invocation is a separate operation, and the function value can be kept for later. |
| Requiring the argument count to equal the parameter count | Ordinary calls do not enforce exact arity. Bind the values that exist, then handle missing and extra values according to parameter rules. |
| Assuming the last expression of every body becomes the result | Implicit return belongs only to an arrow expression body. Ordinary bodies and arrow block bodies produce a value only through an executed return; otherwise the call result is undefined. |
| Treating null as missing, or treating rest as a count or an automatically nested Array | Defaults recognize missing or undefined arguments, not every falsy value. A final rest parameter gathers the remaining values directly into an Array; nesting occurs only when an incoming value is itself an Array. |
Try it
A function has parameters a and b, no defaults, and is called with only the argument 7. Which statements are true? Select all that apply.
- The call is allowed to proceed
- The call throws because every parameter requires an argument
- Parameter b receives undefined
- Parameter b automatically receives null
add is written as (a, b) => a + b, and values is [2, 3]. What does add(...values) return?
- 5
- The array [2, 3]
- The values are gathered into a rest parameter instead
- A TypeError because arrays cannot supply arguments
A factory call creates a local count binding and returns an inner function that reads count. The factory call has finished. Why can the inner function still read count?
- All local bindings automatically become global
- The factory call remains permanently active on the call stack
- The caller recreates count before every inner call
- The inner function retains its creation scope through a closure