Lab 03: Functions, Scope & Closures

🎯 Objective

Master JavaScript functions — declarations, expressions, arrow functions, default parameters, closures, and the this keyword.

📚 Background

JavaScript has first-class functions — functions are objects and can be stored in variables, passed as arguments, and returned from other functions. This enables powerful patterns like callbacks, higher-order functions, and closures. JavaScript also has lexical scoping — a function sees the variables from where it was defined, not where it was called. Understanding closures and this is what separates intermediate from advanced JS developers.

⏱️ Estimated Time

35 minutes

📋 Prerequisites

  • Lab 2: Variables, Data Types & Type Coercion

🛠️ Tools Used

  • Node.js 20

🔬 Lab Instructions

Step 1: Function Declaration vs Expression

📸 Verified Output:

💡 Hoisting moves function declarations to the top of their scope before execution. Function expressions and arrow functions are NOT hoisted — this is one reason to prefer consistent placement of all functions.

Step 2: Arrow Functions

📸 Verified Output:

Step 3: Default Parameters and Rest/Spread

📸 Verified Output:

Step 4: Closures

📸 Verified Output:

Step 5: Higher-Order Functions

📸 Verified Output:

Step 6: Scope — var vs let Hoisting

📸 Verified Output:

Step 7: IIFE and Module Pattern

📸 Verified Output:

Step 8: Memoization with Closures

📸 Verified Output:

✅ Verification

Expected output:

🚨 Common Mistakes

  1. Arrow functions and this: Arrow functions don't have their own this — they inherit from the surrounding scope.

  2. var in loops: for (var i = 0; i < 5; i++) setTimeout(() => console.log(i)) prints 5 five times — use let.

  3. Forgetting return in multi-line arrow functions: const f = x => { x * 2 } returns undefined; need return.

  4. Closures in loops: Classic bug — all closures capture the same variable; use let or IIFE.

  5. arguments object: Arrow functions don't have arguments — use rest params ...args instead.

📝 Summary

  • function declarations are hoisted; expressions/arrows are not

  • Arrow functions: (params) => expression for concise functions

  • Default params: function f(x, y = 10) — evaluated at call time

  • Rest ...args collects extras into array; spread ...arr expands into arguments

  • Closure: inner function captures outer scope variables (private state pattern)

  • Higher-order functions: take/return functions — enables map, filter, reduce, memoize

🔗 Further Reading

Last updated