Episode 1 — Fundamentals / 1.20 — Functions

1.20 — Functions: Quick Revision

Compact cheat sheet. Print-friendly.

How to use this material (instructions)

  1. Skim before labs or interviews.
  2. Drill gaps — reopen README.md1.20.a1.20.g.
  3. Practice1.20-Exercise-Questions.md.
  4. Polish answers1.20-Interview-Questions.md.

Defining functions

StyleSyntaxHoisted?
Declarationfunction name() {}Yes (fully)
Expressionconst name = function() {}No
Arrowconst name = () => {}No
IIFE(function() {})()Runs immediately

Declaration vs expression

Declaration → hoisted → callable BEFORE the line it appears on
Expression  → NOT hoisted → callable ONLY after assignment

Arrow function rules

const a = () => expr;           // no params, implicit return
const b = x => expr;            // one param (parens optional)
const c = (x, y) => expr;      // multiple params
const d = (x) => ({ key: x }); // return object literal — WRAP in ()
const e = (x) => { /* ... */ return val; }; // block body — explicit return
FeatureRegularArrow
Own thisYesNo (lexical)
Own argumentsYesNo
Constructable (new)YesNo
Implicit returnNoYes (no {})

Parameters & arguments

Parameters = names in definition    Arguments = values in call
Missing argument → undefined        Extra arguments → ignored
function fn(a, b = 10, ...rest) { }
//           ↑   ↑ default  ↑ rest (real Array, must be last)
  • null does NOT trigger default. undefined DOES.
  • arguments object: legacy, array-like, not in arrows → use ...rest instead.

Pass-by-value vs reference behavior

PassedMutation inside fnReassignment inside fn
PrimitiveN/ADoes NOT affect outer
ObjectAFFECTS outerDoes NOT affect outer

Return values

return value;  → sends value back + exits function
no return      → returns undefined
return;        → returns undefined

Multiple values: return { a, b } or [a, b] and destructure at call site.

Early return: guard clauses at top → flat, readable code.


Scope

LevelCreated byvarlet/const
GlobalTop levelYesYes
Functionfunction bodyYesYes
Block{ } (if, for, etc.)NoYes

Lexical scoping: variable access determined by WHERE the function is WRITTEN, not where called.

Scope chain: current → parent → ... → global. Not found? ReferenceError.

Shadowing: inner variable with same name hides outer one.


Closures

Closure = function + reference to its lexical scope
  • Inner function retains access to outer variables after outer function returns.
  • Enables: private state, factories, memoization, module pattern.
function make(x) {
  return (y) => x + y;  // closes over x
}
const add5 = make(5);
add5(3); // 8

Classic bug: var in for loop + setTimeout → all callbacks see final i. Fix: use let.


Pure functions

Same input → ALWAYS same output + NO side effects

Side effects: mutating external state, DOM writes, network calls, console.log, timers.

Strategy: pure core logic + side effects at edges.


Higher-order functions

Takes a function as argument  OR  returns a function

Built-in: .map(), .filter(), .reduce(), .sort(), .forEach(), setTimeout()


Recursion

function rec(input) {
  if (BASE_CASE) return value;      // STOP
  return rec(smallerInput);         // RECURSE toward base
}
  • Call stack: one frame per call; too deep → stack overflow.
  • Memoization: cache results to avoid redundant calls.
  • Best for: trees, nested data, divide-and-conquer.
  • TCO: in spec, only Safari supports — do not rely on it.

Naming conventions

PrefixReturnsExample
get*ValuegetUser()
set*Void/confirmsetTheme()
is* / has* / can*BooleanisValid()
create* / make*New thingcreateUser()
handle*Void (event)handleClick()
validate*Void/throwvalidateEmail()
format*StringformatDate()

IIFE

(function () { /* isolated scope */ })();
(() => { /* arrow IIFE */ })();

Purpose: scope isolation, module pattern (pre-ES6), one-time init.


Common pitfalls

PitfallSymptomFix
Call expression before constReferenceErrorMove call after, or use declaration
Arrow as object methodthis is wrongUse regular function / shorthand
() => { key: val }Returns undefinedWrap in (): () => ({ key: val })
var in loop + asyncAll callbacks share same iUse let
Recursion no base caseStack overflowAdd base case
Mutation of passed objectCaller's data changedShallow copy first

Master workflow

  1. Define — declaration (hoisted helper) or arrow (callback/inline).
  2. Parameters — defaults, rest, destructuring. Validate early.
  3. Return — explicit value. Early return for guards.
  4. Scope — minimize globals, prefer const/let, understand closures.
  5. Reuse — DRY, SRP, pure functions, compose, document with JSDoc.
  6. Recurse — only for nested/tree data; always have a base case.

End of 1.20 quick revision.