Course

Web Development
  • 1.1 Introduction to the Web
  • 2.1 HTML Basics
  • 2.2 Text & Content
  • 2.3 Layout & Grouping
  • 2.4 Lists & Tables
  • 2.5 Media & Embedding
  • 2.6 Forms
  • 2.7 Semantic HTML
  • 2.8 Accessibility & SEO
  • 3.1 CSS Introduction
  • 3.2 CSS Syntax
  • 3.3 CSS Selectors
  • 3.4 Typography
  • 3.5 Colors & Backgrounds
  • 3.6 Text Styling
  • 3.7 Box Model
  • 3.8 Units
  • 3.9 Display & Positioning
  • 3.10 Layout Systems
  • 3.11 Responsive Design
  • 3.12 Animations
  • 3.13 Modern CSS
  • 3.14 Performance & Accessibility
  • 3.15 Tailwind CSS Basics
  • 4.1 Introduction to JavaScript
  • 4.2 Variables & Scope
  • 4.3 Data Types
  • 4.4 Type Conversion
  • 4.5 Operators
  • 4.6 Control Flow
  • 4.7 Loops
  • 4.8 Functions
  • 4.9 Advanced Functions
  • 4.10 Objects & Arrays
  • 4.11 The this Keyword

4.9 Advanced Functions

Updated Jul 23, 2026

4.9 Advanced Functions

Updated Jul 23, 2026

4.9 Advanced Functions

Functions become even more powerful when combined with concepts like scope, closures, and the call stack.

These concepts are used extensively in modern JavaScript frameworks such as:

  • React
  • Next.js
  • Node.js
  • Event Handling
  • React Hooks
  • Asynchronous JavaScript

Understanding these topics is essential before learning advanced JavaScript and React.


Scope

Scope determines where variables can be accessed.

Think of scope as the visibility area of a variable.

Inside Scope  → Accessible

Outside Scope → Not Accessible

Types of Scope

JavaScript has three main types of scope:

  1. Global Scope
  2. Function Scope
  3. Block Scope

Global Scope

Variables declared outside of any function belong to the global scope.

They can be accessed anywhere in the program.

const name = "Samir";

function greet() {

    console.log(name);

}

greet();

Output

Samir

Visualization

Global Scope
│
├── name
├── greet()
└── other functions

Every function can access global variables.


Function Scope

Variables declared inside a function exist only inside that function.

function greet() {

    const message = "Hello";

    console.log(message);

}

greet();

Output

Hello

Outside the function

console.log(message);

Output

ReferenceError

Visualization

greet()
│
└── message

Block Scope

Variables declared using let or const are block scoped.

if (true) {

    const age = 21;

}

console.log(age);

Output

ReferenceError

Visualization

{
    age
}

The variable exists only inside the block.


Scope Chain

When JavaScript looks for a variable, it searches from the innermost scope outward.

const country = "Nepal";

function outer() {

    function inner() {

        console.log(country);

    }

    inner();

}

outer();

Output

Nepal

Search Order

Current Scope
      ↓
Parent Scope
      ↓
Global Scope

This process is called the Scope Chain.


Lexical Scope

Lexical means:

Determined By Position In Code

A function can access variables from the place where it was defined, not where it is called.

const name = "Samir";

function greet() {

    console.log(name);

}

greet();

Output

Samir

Why?

Because greet() was created inside the scope where name exists.


Another Example

function outer() {

    const message = "Hello";

    function inner() {

        console.log(message);

    }

    inner();

}

outer();

Output

Hello

Visualization

Global Scope
│
└── outer()
     │
     └── message
           │
           └── inner()

inner() can access message because of lexical scope.


Closures

A Closure occurs when a function remembers variables from its lexical scope even after the outer function has finished executing.

Closures are one of the most important concepts in JavaScript.


Basic Closure Example

function outer() {

    const name = "Samir";

    function inner() {

        console.log(name);

    }

    return inner;

}

const fn = outer();

fn();

Output

Samir

Why Does This Work?

Even though outer() has already finished executing, the returned function still remembers the variable name.

This memory is called a Closure.


Visualization

outer()
│
├── name = "Samir"
│
└── returns inner()

After outer() finishes

│
└── inner() still remembers name

Real-World Closure Example

function counter() {

    let count = 0;

    return function() {

        count++;

        console.log(count);

    };

}

const increment = counter();

increment();
increment();
increment();

Output

1
2
3

The inner function remembers the count variable through a closure.


Another Closure Example

function createGreeting(name) {

    return function() {

        console.log(
            `Hello ${name}`
        );

    };

}

const greetSamir =
createGreeting("Samir");

greetSamir();

Output

Hello Samir

Why Closures Matter

Closures are heavily used in:

  • React Hooks
  • Event Listeners
  • Timers
  • Callbacks
  • Private Variables
  • State Management

Almost every modern JavaScript application uses closures.


Call Stack

JavaScript uses a Call Stack to keep track of function execution.

It follows the Last In, First Out (LIFO) principle.

Last In
   ↓
First Out

Example

function one() {

    two();

}

function two() {

    three();

}

function three() {

    console.log("Done");

}

one();

Execution Flow

Start

↓

one()

↓

two()

↓

three()

↓

console.log()

↓

Complete

↓

three() removed

↓

two() removed

↓

one() removed

Visual Stack

┌──────────────┐
│ console.log  │
├──────────────┤
│ three()      │
├──────────────┤
│ two()        │
├──────────────┤
│ one()        │
└──────────────┘

The last function added is the first one removed.


Stack Overflow

If recursive functions never stop, the call stack keeps growing.

function test() {

    test();

}

test();

Output

RangeError:
Maximum call stack size exceeded

Every recursive function must have a stopping condition.


Built-in Functions

JavaScript includes many built-in functions.

These are available without creating them yourself.


Number Functions

parseInt()

parseInt("100");

Output

100

parseFloat()

parseFloat("99.99");

Output

99.99

isNaN()

isNaN("Hello");

Output

true

Number()

Number("100");

Output

100

String Functions

String()

String(123);

Output

"123"

Example

const text = "hello";

console.log(
    text.toUpperCase()
);

Output

HELLO

Math Functions

JavaScript provides the built-in Math object.


Random Number

Math.random();

Output

0.34872

(Random value between 0 and 1)


Round

Math.round(4.6);

Output

5

Floor

Math.floor(4.9);

Output

4

Max

Math.max(
    10,
    20,
    30
);

Output

30

Date Functions

Current Date

new Date();

Returns the current date and time.


Current Year

new Date().getFullYear();

Example Output

2026

Console Functions

console.log()

console.log("Hello");

console.error()

console.error("Error");

console.table()

console.table([
    "Apple",
    "Mango"
]);

Displays data in a table format inside the browser console.


Timer Functions

setTimeout()

Runs a function once after a delay.

setTimeout(() => {

    console.log("Hello");

}, 2000);

Output after:

2 Seconds

setInterval()

Runs a function repeatedly.

setInterval(() => {

    console.log("Running");

}, 1000);

Output

Every Second

Common Global Built-in Functions

Function Purpose
parseInt() Convert String → Integer
parseFloat() Convert String → Decimal
Number() Convert to Number
String() Convert to String
Boolean() Convert to Boolean
isNaN() Check if value is NaN
setTimeout() Execute once after delay
setInterval() Execute repeatedly

Scope vs Closure

Scope Closure
Determines variable visibility Remembers variables
Exists while executing Exists after outer function finishes
Controls access Preserves data
Temporary Persistent

Real-World Example

function createCounter() {

    let count = 0;

    return () => {

        count++;

        return count;

    };

}

const counter =
createCounter();

console.log(counter());

console.log(counter());

console.log(counter());

Output

1
2
3

Concepts used

Function
      ↓
Lexical Scope
      ↓
Closure
      ↓
Call Stack

Summary

Concept Purpose
Scope Variable visibility
Global Scope Accessible everywhere
Function Scope Accessible inside functions
Block Scope Accessible inside blocks
Lexical Scope Variables found based on code location
Closure Function remembers variables
Call Stack Tracks function execution
Built-in Functions Ready-made JavaScript functions

Best Practices

Prefer const and let

Avoid using var in modern JavaScript.

const name = "Samir";

let count = 0;

Keep Variables in the Smallest Scope

Declare variables only where they are needed.

function calculate() {

    const total = 100;

}

Use Closures Carefully

Closures are powerful but can keep variables in memory.

Only retain data that is actually needed.


Always Include a Base Case in Recursion

if (n === 0) {

    return;

}

Without a base case, recursion causes a stack overflow.


Clear Timers When No Longer Needed

const timer = setInterval(() => {

    console.log("Running");

}, 1000);

clearInterval(timer);

This helps prevent memory leaks.


Key Takeaway

Advanced functions are built on three fundamental ideas:

Scope
   ↓
Where Variables Can Be Accessed

Lexical Scope
        ↓
How Functions Find Variables

Closures
     ↓
How Functions Remember Variables

JavaScript executes every function using the Call Stack.

Call Stack
     ↓
Function Execution Order

These concepts are the foundation of React Hooks, event handlers, callbacks, timers, state management, and modern frontend development. Mastering them will make it much easier to understand advanced JavaScript and frameworks like React and Next.js.

4.8 Functions4.10 Objects & Arrays