π¨ JavaScript Β· Topic 11 of 20
Functions & Arrow Functions β JavaScript Questions with Answers
30 practice questions on Functions & Arrow Functions, each with the correct answer and a clear explanation of why it is right. Read through them as revision notes, or take this topic as an interactive quiz to test yourself.
3 easy Β· 16 medium Β· 11 hard Β· Part of JavaScript: The language of the web - basics to advanced, 20 topics.
Medium questions (16)
Q2. medium
What is the key practical difference between a function declaration and an expression?
sayHi(); // works
function sayHi() { }
sayBye(); // TypeError/ReferenceError
const sayBye = function() { };
- A Declarations are fully HOISTED, so they can be called before they appear; expressions cannot
- B Expressions run faster
- C Declarations cannot take parameters
- D There is no difference
Answer: A β Declarations are fully HOISTED, so they can be called before they appear; expressions cannot
Declarations are lifted with their body, so calling them earlier in the file works. Function expressions follow variable hoisting rules, so calling early gives an error.
Hoisting
Q5. medium
When can you omit the parentheses around an arrow function's parameter?
() => 42
n => n * 2
(a, b) => a + b
- A With exactly ONE parameter: n => n * 2
- B Always
- C Never
- D Only with zero parameters
Answer: A β With exactly ONE parameter: n => n * 2
Zero parameters need (), and two or more need (a, b). A single parameter may drop them - though many style guides require them for consistency.
Arrow syntax
Q7. medium
How do you give a parameter a DEFAULT value?
function greet(name = "Guest") { return `Hi ${name}`; }
greet(); // Hi Guest
greet(undefined); // Hi Guest
greet(null); // Hi null - null is NOT undefined!
- A function greet(name = "Guest") { }
- B function greet(name || "Guest") { }
- C function greet(name: "Guest") { }
- D function greet(default name) { }
Answer: A β function greet(name = "Guest") { }
Default parameters (ES6) apply when the argument is undefined (including when omitted). They may reference earlier parameters too.
Default parameters
Q8. medium
What happens when you call a function with FEWER arguments than parameters?
- A The missing parameters are undefined - no error is thrown
- B TypeError
- C The call is ignored
- D They default to 0
Answer: A β The missing parameters are undefined - no error is thrown
JavaScript never enforces argument counts. Extra arguments are ignored; missing ones become undefined. This flexibility makes defaults and validation important.
Argumentsundefined
Q9. medium
What do REST parameters do?
function sum(...nums) { }
function sum(...nums) {
return nums.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3)); // 6
- A Collect all remaining arguments into a real ARRAY
- B Spread an array into arguments
- C Limit the function to 3 arguments
- D Create optional parameters
Answer: A β Collect all remaining arguments into a real ARRAY
...nums gathers any number of arguments into an array you can map/reduce over. It must be the LAST parameter.
Rest parametersSpread
Q12. medium
What is a callback function?
setTimeout(() => console.log("later"), 1000);
btn.addEventListener("click", handleClick);
[1,2].map(n => n * 2);
- A A function passed to another function to be called later
- B A function that calls itself
- C A function that returns a function
- D A built-in browser function
Answer: A β A function passed to another function to be called later
Callbacks power event handlers, timers and array methods: you hand over a function and the other code decides when to run it.
CallbacksHigher-order functions
Q14. medium
What is a higher-order function?
- A A function that takes a function as an argument and/or returns a function
- B A function with many parameters
- C A function declared first in a file
- D A recursive function
Answer: A β A function that takes a function as an argument and/or returns a function
map, filter, addEventListener and setTimeout are all higher-order. Functions being first-class values (storable, passable, returnable) is what makes this possible.
First-class functionsmap
Q16. medium
What is function recursion?
function factorial(n) {
if (n <= 1) return 1; // base case
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
- A A function calling ITSELF, with a base case to stop
- B Two functions calling each other only
- C A loop inside a function
- D Calling a function twice
Answer: A β A function calling ITSELF, with a base case to stop
Recursion breaks a problem into smaller identical problems. Every recursive function needs a base case, or it hits 'Maximum call stack size exceeded'.
RecursionCall stack
Q17. medium
What error does infinite recursion cause?
- A RangeError: Maximum call stack size exceeded
- B SyntaxError
- C TypeError
- D It runs forever silently
Answer: A β RangeError: Maximum call stack size exceeded
Each call adds a frame to the call stack; without a base case the stack overflows. The error message is the signature of a missing or unreachable base case.
Call stackRangeError
Q20. medium
What is a pure function?
const add = (a, b) => a + b; // pure
let total = 0;
const addTo = n => { total += n; }; // impure (side effect)
- A One that returns the same output for the same input and causes no side effects
- B A function with no parameters
- C An arrow function
- D A function that only uses const
Answer: A β One that returns the same output for the same input and causes no side effects
Pure functions do not modify external state, DOM or their arguments. They are easy to test, cache and reason about - the backbone of functional style and React.
PuritySide effects
Q23. medium
What is the output?
const nums = [1, 2, 3];
console.log(nums.map(function(n) { return n * 2; }));
- A [2, 4, 6]
- B [1, 2, 3]
- C undefined
- D Error
Answer: A β [2, 4, 6]
An anonymous function expression works exactly like an arrow here. The arrow version is shorter: nums.map(n => n * 2).
Anonymous functionsmap
Q24. medium
What is a named function expression useful for?
const f = function myFunc() { };
- A The name appears in stack traces and allows self-reference inside the function
- B It creates two functions
- C It is required by strict mode
- D It makes it global
Answer: A β The name appears in stack traces and allows self-reference inside the function
The internal name aids debugging and recursion, but is not visible outside the function - only f exists in the enclosing scope.
Named expressionsDebugging
Q26. medium
How do you write a function that takes an options OBJECT?
create({ height: 80 }); // width defaults to 100
create(); // both defaults
- A function create({ width = 100, height = 50 } = {}) { }
- B function create(options[]) { }
- C function create(width, height, ...) { }
- D function create(object) { }
Answer: A β function create({ width = 100, height = 50 } = {}) { }
Destructuring with defaults, plus '= {}' so calling with no arguments still works. Callers pass named options in any order - self-documenting and easy to extend.
DestructuringOptions pattern
Q27. medium
What is the output?
console.log(typeof function() {});
if (typeof callback === "function") callback();
- A "function"
- B "object"
- C "undefined"
- D "method"
Answer: A β "function"
Functions are objects internally, but typeof reports "function" - the standard way to check whether something is callable before calling it.
typeofCallbacks
Q29. medium
Which naming style is conventional for functions?
- A camelCase verbs: calculateTotal(), getUserById()
- B PascalCase: CalculateTotal()
- C snake_case: calculate_total()
- D ALL_CAPS
Answer: A β camelCase verbs: calculateTotal(), getUserById()
Functions do things, so names usually start with a verb in camelCase. PascalCase is reserved for classes and React components.
ConventionsNaming
Q30. medium
Why break code into small functions?
- A Reuse, easier testing, self-documenting names, and no duplicated logic
- B Functions always run faster
- C JavaScript requires at least five
- D To use more memory
Answer: A β Reuse, easier testing, self-documenting names, and no duplicated logic
A well-named function replaces a comment and can be tested in isolation. The DRY principle - Don't Repeat Yourself - is the core motivation.
DRYCode organisation
Hard questions (11)
Q6. hard
What is the output?
const f = n => { n * 2 };
console.log(f(5));
- A undefined - braces create a block body, which needs an explicit return
- B 10
- C 5
- D SyntaxError
Answer: A β undefined - braces create a block body, which needs an explicit return
Curly braces switch the arrow to a full function body. Either remove them (n => n * 2) or add return (n => { return n * 2; }). A very common bug inside map().
Arrow functionsCommon mistakes
Q10. hard
What is the difference between rest (...) in a definition and spread (...) in a call?
function sum(...nums) { } // rest: gather
sum(...[1, 2, 3]); // spread: scatter
- A Rest COLLECTS arguments into an array; spread EXPANDS an array into separate arguments
- B They are the same
- C Rest only works with numbers
- D Spread only works in definitions
Answer: A β Rest COLLECTS arguments into an array; spread EXPANDS an array into separate arguments
Same three dots, opposite directions - context decides. Definition side = gather; call side = scatter.
RestSpread
Q11. hard
What is the arguments object, and do arrow functions have it?
function old() { console.log(arguments[0]); }
const modern = (...args) => console.log(args[0]); // preferred
- A An array-LIKE object of all passed arguments in regular functions - arrow functions do NOT have it
- B A real array available everywhere
- C Only available in arrow functions
- D It stores return values
Answer: A β An array-LIKE object of all passed arguments in regular functions - arrow functions do NOT have it
arguments exists in traditional functions but is not a real array (no map/filter). Arrow functions inherit it from the enclosing scope instead. Modern code prefers rest parameters.
argumentsRest parameters
Q13. hard
What is the difference between passing greet and greet()?
btn.addEventListener("click", greet);
btn.addEventListener("click", greet); // correct
btn.addEventListener("click", greet()); // WRONG - runs now
btn.addEventListener("click", () => greet(1)); // correct with args
- A greet passes the FUNCTION itself; greet() CALLS it immediately and passes its return value
- B They are identical
- C greet() is required for events
- D greet is invalid
Answer: A β greet passes the FUNCTION itself; greet() CALLS it immediately and passes its return value
Adding parentheses runs the function right away and registers whatever it returned (usually undefined) as the handler - so nothing happens on click. Omit them, or wrap in an arrow: () => greet(arg).
- A top-three beginner bug with event listeners.
CallbacksEvents
Q15. hard
What is an IIFE?
(function() { ... })();
(function() {
const secret = 42; // not global
})();
(() => { /* arrow IIFE */ })();
- A Immediately Invoked Function Expression - it runs the moment it is defined, creating a private scope
- B A function that never runs
- C An imported function
- D A class constructor
Answer: A β Immediately Invoked Function Expression - it runs the moment it is defined, creating a private scope
Before ES6 modules, IIFEs were the way to avoid polluting the global scope. The wrapping parentheses turn the declaration into an expression, and the trailing () invokes it.
IIFEScope
Q18. hard
What is the output?
function f(x) { x = 99; }
let a = 5;
f(a);
console.log(a);
- A 5 - primitives are passed BY VALUE, so the function got a copy
- B 99
- C undefined
- D Error
Answer: A β 5 - primitives are passed BY VALUE, so the function got a copy
Reassigning a parameter only changes the local copy. To change the caller's value, return the new one and reassign.
Pass by valuePrimitives
Q19. hard
What is the output?
function f(obj) { obj.n = 99; }
const o = { n: 5 };
f(o);
console.log(o.n);
function g(obj) { obj = { n: 0 }; } // no outside effect
g(o);
console.log(o.n); // still 99
- A 99 - objects are passed by reference VALUE, so mutations are visible outside
- B 5
- C undefined
- D Error
Answer: A β 99 - objects are passed by reference VALUE, so mutations are visible outside
The parameter points at the same object, so mutating its properties affects the caller. But REASSIGNING the parameter (obj = {}) would not - the reference itself was copied.
Pass by referenceMutation
Q21. hard
How do arrow functions differ from regular functions regarding this?
const timer = {
count: 0,
start() {
setInterval(() => this.count++, 1000); // arrow keeps this
}
};
- A Arrows have no own this - they inherit it from the surrounding scope (lexical this)
- B Arrows always set this to window
- C They behave identically
- D Arrows set this to undefined always
Answer: A β Arrows have no own this - they inherit it from the surrounding scope (lexical this)
This is the biggest practical difference. Arrows are perfect for callbacks inside methods (where you want the outer this) and wrong as object methods (where you want the object).
thisArrow functions
Q22. hard
Which is NOT true of arrow functions?
- A They can be used as constructors with new
- B They have no own this
- C They have no arguments object
- D They can have implicit returns
Answer: A β They can be used as constructors with new
Arrow functions cannot be called with new - 'is not a constructor'. They also lack prototype, this, arguments and super. Use regular functions or classes for constructors.
Arrow limitationsConstructors
Q25. hard
What does this return?
function add(a) { return b => a + b; }
const add5 = add(5);
console.log(add5(3));
- A 8 - add returns a function that remembers a (a closure)
- B 5
- C 3
- D undefined
Answer: A β 8 - add returns a function that remembers a (a closure)
add(5) produces a specialised function with a fixed at 5. This technique - a function returning a function - is called currying and relies on closures.
ClosuresCurrying
Q28. hard
What is the output?
function f() { return;
42; }
console.log(f());
return { // correct - brace on the same line
a: 1
};
- A undefined - Automatic Semicolon Insertion ends the return statement at the line break
- B 42
- C SyntaxError
- D null
Answer: A β undefined - Automatic Semicolon Insertion ends the return statement at the line break
ASI inserts a semicolon right after return, making 42 unreachable code. Always put the returned value on the SAME line as return - especially with multi-line objects (use a parenthesis on the return line).
ASIreturnGotchas