|

JavaScript 10 🧬 Functions

Functions are blocks of code designed to perform a specific task. They play a crucial role in organizing and structuring code — allowing you to write reusable, maintainable, and modular programs.


A Quick Look at the Examples

// Function declaration
function greet() {
    return "Hello World";
}
console.log(greet()); // "Hello World"

// Function expression
const greet2 = function(name) {
    return "Hello World";
};
console.log(greet2()); // "Hello World"

// Function with parameters
function add(a, b) {
    return a + b;
}
let result = add(5, 3);
console.log(result); // 8

// Default arguments (ES6)
function greet3(name = "Guest") {
    return "Hello, " + name;
}
console.log(greet3());         // "Hello, Guest"
console.log(greet3("Kronos")); // "Hello, Kronos"

// Simulating default arguments (pre-ES6)
function greet4(name) {
    if (name === undefined) {
        name = "Guest";
    }
    return "Hello, " + name;
}
console.log(greet4()); // "Hello, Guest"

a. Functions Introduction

Functions are blocks of code designed to perform a specific task. They can be defined using the function keyword or arrow syntax (ES6). They play a crucial role in organizing and structuring code.

Key Concept: Hoisting

Function declarations are hoisted — meaning they can be called before they are defined in the code.

// This works — function declarations are hoisted
sayHello(); // "Hello!"

function sayHello() {
    console.log("Hello!");
}

Two Ways to Define Functions

TypeSyntaxHoisted?
Function Declarationfunction greet() { }✅ Yes
Function Expressionconst greet = function() { }❌ No
Arrow Function (ES6)const greet = () => { }❌ No

1. Function Declaration

function greet(name) {
    return "Hello, " + name;
}

greet("World"); // "Hello, World"

Key Points:

  • Uses the function keyword
  • Hoisted — can be called before definition
  • Named function

2. Function Expression

const greet2 = function(name) {
    return "Hello, " + name;
};

greet2("World"); // "Hello, World"

Key Points:

  • Assigned to a variable
  • NOT hoisted — must be defined before calling
  • Can be anonymous or named

3. Arrow Function (ES6)

const greet3 = (name) => {
    return "Hello, " + name;
};

// Concise body (implicit return)
const greet4 = (name) => "Hello, " + name;

// Single parameter (no parentheses needed)
const greet5 = name => "Hello, " + name;

greet3("World"); // "Hello, World"

Key Points:

  • Shorter syntax
  • No own this binding
  • Always anonymous
  • Not hoisted

Hoisting Comparison

// ✅ Works — function declaration is hoisted
sayHi();
function sayHi() { console.log("Hi!"); }

// ❌ TypeError — function expression is not hoisted
sayHello();
const sayHello = function() { console.log("Hello!"); };
// sayHello is hoisted as undefined, so calling it fails

// ❌ ReferenceError — arrow function is not hoisted
sayHey();
const sayHey = () => console.log("Hey!");

b. Function Arguments and Return Value

Functions can accept inputs known as arguments and return outputs.

Parameters vs Arguments

TermDefinitionExample
ParametersNames listed in the function definitionfunction add(a, b)a and b are parameters
ArgumentsActual values passed when callingadd(5, 3)5 and 3 are arguments

Function with Parameters

function add(a, b) {
    return a + b;
}

let result = add(5, 3);
console.log(result); // 8

What happens:

  1. a gets 5, b gets 3
  2. return a + b returns 8
  3. result is assigned 8

The return Statement

  • Ends function execution immediately
  • Returns a value to the caller
  • If no return, the function returns undefined
// Returns a value
function multiply(a, b) {
    return a * b;
}
console.log(multiply(4, 5)); // 20

// No return — returns undefined
function logMessage(msg) {
    console.log(msg);
    // no return statement
}
console.log(logMessage("Hi")); // "Hi" then undefined

// Early return
function checkAge(age) {
    if (age < 18) {
        return "Minor";
    }
    return "Adult"; // Only reached if age >= 18
}
console.log(checkAge(15)); // "Minor"
console.log(checkAge(25)); // "Adult"

Arguments Object (Pre-ES6)

Every function has access to an arguments object — an array-like object containing all arguments passed.

function sum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return total;
}
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(5, 10));      // 15

Note: Arrow functions do not have an arguments object. Use rest parameters instead.

Rest Parameters (ES6)

function sum(...numbers) {
    return numbers.reduce((total, n) => total + n, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(5, 10));      // 15

Missing Arguments

If you call a function with fewer arguments than parameters, missing ones are undefined.

function greet(name, greeting) {
    return greeting + ", " + name;
}
console.log(greet("Alice")); // "undefined, Alice" ⚠️

Strict mode: In strict mode, missing arguments are still undefined — but you’ll get better error messages.

Extra Arguments

If you pass more arguments than parameters, extra ones are ignored (but accessible via arguments).

function add(a, b) {
    return a + b;
}
console.log(add(1, 2, 3, 4)); // 3 (extra arguments ignored)

c. Function Default Arguments

Introduced in ES6, default arguments allow functions to have parameters with predefined values — used if no argument or undefined is passed.

Syntax

function greet(name = "Guest") {
    return "Hello, " + name;
}

console.log(greet());         // "Hello, Guest" (default used)
console.log(greet("Kronos")); // "Hello, Kronos" (argument used)
console.log(greet(undefined)); // "Hello, Guest" (default used)
console.log(greet(null));     // "Hello, null" (null is NOT undefined!)

Key Points:

  • Default is used only when argument is undefined (or missing)
  • null does not trigger the default
  • Can reference previous parameters

Multiple Default Parameters

function createUser(name = "Anonymous", age = 0, role = "User") {
    return { name, age, role };
}

console.log(createUser());                          // { name: "Anonymous", age: 0, role: "User" }
console.log(createUser("Alice"));                   // { name: "Alice", age: 0, role: "User" }
console.log(createUser("Bob", 25));                 // { name: "Bob", age: 25, role: "User" }
console.log(createUser("Carol", 30, "Admin"));      // { name: "Carol", age: 30, role: "Admin" }

Defaults with Expressions

function greet(name = "Guest", greeting = `Hello, ${name}`) {
    return greeting;
}

console.log(greet());           // "Hello, Guest"
console.log(greet("Alice"));    // "Hello, Alice"
console.log(greet("Bob", "Hi")); // "Hi"

Simulating Optional Parameters (Pre-ES6)

Before ES6, you had to check for undefined manually:

function greet(name) {
    if (name === undefined) {
        name = "Guest";
    }
    return "Hello, " + name;
}

console.log(greet());         // "Hello, Guest"
console.log(greet("Kronos")); // "Hello, Kronos"

Modern equivalent:

function greet(name) {
    name = name || "Guest"; // Falsy check (but "" and 0 would trigger default!)
    return "Hello, " + name;
}

⚠️ Warning: The || approach treats "", 0, false, and NaN as falsy — use ?? (nullish coalescing) or === undefined for precise behavior.

// Modern approach with nullish coalescing
function greet(name) {
    name = name ?? "Guest"; // Only null/undefined trigger default
    return "Hello, " + name;
}

Complete Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript Functions</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background: #f8f9fa;
            color: #333;
            line-height: 1.6;
        }
        h1 { color: #007bff; border-bottom: 3px solid #007bff; padding-bottom: 10px; }
        h2 { color: #28a745; border-left: 4px solid #28a745; padding-left: 15px; margin-top: 30px; }
        .demo-box {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            margin: 15px 0;
        }
        pre {
            background: #1e1e1e;
            color: #d4d4d4;
            padding: 15px;
            border-radius: 8px;
            overflow-x: auto;
            font-family: 'Courier New', monospace;
            font-size: 0.9rem;
            line-height: 1.8;
        }
        .keyword { color: #569cd6; }
        .string { color: #ce9178; }
        .number { color: #b5cea8; }
        .function { color: #dcdcaa; }
        .comment { color: #6a9955; }
        .boolean { color: #569cd6; }
        #output {
            background: #e9ecef;
            padding: 15px;
            border-radius: 8px;
            margin-top: 15px;
            min-height: 40px;
            font-family: 'Courier New', monospace;
            font-size: 0.85rem;
            border-left: 4px solid #007bff;
            white-space: pre-wrap;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin: 15px 0;
        }
        th, td {
            padding: 10px;
            border: 1px solid #ddd;
            text-align: left;
        }
        th { background: #007bff; color: white; }
        tr:nth-child(even) { background: #f8f9fa; }
    </style>
</head>
<body>

    <h1>JavaScript Functions</h1>

    <div class="demo-box">
        <h2>1. Function Declarations vs Expressions</h2>
        <pre>
<span class="comment">// Function declaration (hoisted)</span>
<span class="keyword">function</span> <span class="function">greet</span>() {
    <span class="keyword">return</span> <span class="string">"Hello World"</span>;
}

<span class="comment">// Function expression (not hoisted)</span>
<span class="keyword">const</span> greet2 = <span class="keyword">function</span>(name) {
    <span class="keyword">return</span> <span class="string">"Hello World"</span>;
};

<span class="comment">// Arrow function (ES6)</span>
<span class="keyword">const</span> greet3 = (name) => <span class="string">"Hello, "</span> + name;
        </pre>
    </div>

    <div class="demo-box">
        <h2>2. Parameters and Arguments</h2>
        <pre>
<span class="keyword">function</span> <span class="function">add</span>(a, b) {       <span class="comment">// a, b are parameters</span>
    <span class="keyword">return</span> a + b;
}

<span class="keyword">let</span> result = <span class="function">add</span>(<span class="number">5</span>, <span class="number">3</span>);   <span class="comment">// 5, 3 are arguments</span>
console.log(result);          <span class="comment">// 8</span>
        </pre>
    </div>

    <div class="demo-box">
        <h2>3. Default Arguments (ES6)</h2>
        <pre>
<span class="keyword">function</span> <span class="function">greet</span>(name = <span class="string">"Guest"</span>) {
    <span class="keyword">return</span> <span class="string">"Hello, "</span> + name;
}

console.log(<span class="function">greet</span>());          <span class="comment">// "Hello, Guest"</span>
console.log(<span class="function">greet</span>(<span class="string">"Kronos"</span>));  <span class="comment">// "Hello, Kronos"</span>
        </pre>
    </div>

    <div class="demo-box">
        <h2>4. Simulating Defaults (Pre-ES6)</h2>
        <pre>
<span class="keyword">function</span> <span class="function">greet</span>(name) {
    <span class="keyword">if</span> (name === <span class="boolean">undefined</span>) {
        name = <span class="string">"Guest"</span>;
    }
    <span class="keyword">return</span> <span class="string">"Hello, "</span> + name;
}

console.log(<span class="function">greet</span>()); <span class="comment">// "Hello, Guest"</span>
        </pre>
    </div>

    <div class="demo-box">
        <h2>5. Live Output — Functions</h2>
        <div id="output">Loading...</div>
    </div>

    <script>
        // ============================================
        // Functions — Live Demo
        // ============================================

        let results = [];

        // 1. Function declaration
        function greet() {
            return "Hello World";
        }
        results.push('📌 Function Declaration:\n');
        results.push('  greet() → ' + greet());
        results.push('');

        // 2. Function expression
        const greet2 = function(name) {
            return "Hello, " + name;
        };
        results.push('📌 Function Expression:\n');
        results.push('  greet2("Alice") → ' + greet2("Alice"));
        results.push('');

        // 3. Arrow function
        const greet3 = (name) => "Hello, " + name;
        results.push('📌 Arrow Function:\n');
        results.push('  greet3("Bob") → ' + greet3("Bob"));
        results.push('');

        // 4. Function with parameters
        function add(a, b) {
            return a + b;
        }
        results.push('📌 Parameters and Arguments:\n');
        results.push('  add(5, 3) → ' + add(5, 3));
        results.push('  add(10, 20) → ' + add(10, 20));
        results.push('  add(5) → ' + add(5) + ' (missing arg → NaN)');
        results.push('');

        // 5. Return values
        function multiply(a, b) {
            return a * b;
        }
        results.push('📌 Return Values:\n');
        results.push('  multiply(4, 5) → ' + multiply(4, 5));
        results.push('  multiply(3, 7) → ' + multiply(3, 7));
        results.push('');

        // 6. Default arguments
        function greetDefault(name = "Guest") {
            return "Hello, " + name;
        }
        results.push('📌 Default Arguments:\n');
        results.push('  greetDefault() → ' + greetDefault());
        results.push('  greetDefault("Kronos") → ' + greetDefault("Kronos"));
        results.push('  greetDefault(undefined) → ' + greetDefault(undefined));
        results.push('  greetDefault(null) → ' + greetDefault(null) + ' (null does NOT trigger default)');
        results.push('');

        // 7. Multiple defaults
        function createUser(name = "Anonymous", age = 0, role = "User") {
            return `{ name: "${name}", age: ${age}, role: "${role}" }`;
        }
        results.push('📌 Multiple Defaults:\n');
        results.push('  createUser() → ' + createUser());
        results.push('  createUser("Alice") → ' + createUser("Alice"));
        results.push('  createUser("Bob", 25) → ' + createUser("Bob", 25));
        results.push('  createUser("Carol", 30, "Admin") → ' + createUser("Carol", 30, "Admin"));
        results.push('');

        // 8. Simulating optional parameters (pre-ES6)
        function greetOld(name) {
            if (name === undefined) {
                name = "Guest";
            }
            return "Hello, " + name;
        }
        results.push('📌 Simulating Defaults (Pre-ES6):\n');
        results.push('  greetOld() → ' + greetOld());
        results.push('  greetOld("Kronos") → ' + greetOld("Kronos"));
        results.push('');

        // 9. Rest parameters
        function sum(...numbers) {
            return numbers.reduce((total, n) => total + n, 0);
        }
        results.push('📌 Rest Parameters:\n');
        results.push('  sum(1, 2, 3) → ' + sum(1, 2, 3));
        results.push('  sum(1, 2, 3, 4, 5) → ' + sum(1, 2, 3, 4, 5));
        results.push('');

        // 10. Practical: Form validation
        function validateAge(age) {
            if (typeof age !== 'number' || age < 0 || age > 150) {
                return "Invalid age";
            }
            return age >= 18 ? "Adult" : "Minor";
        }
        results.push('📌 Practical: Form Validation:\n');
        results.push('  validateAge(25) → ' + validateAge(25));
        results.push('  validateAge(15) → ' + validateAge(15));
        results.push('  validateAge(-5) → ' + validateAge(-5));
        results.push('  validateAge("abc") → ' + validateAge("abc"));
        results.push('');

        // 11. Higher-order function
        function applyOperation(a, b, operation) {
            return operation(a, b);
        }
        results.push('📌 Higher-Order Function:\n');
        results.push('  applyOperation(5, 3, add) → ' + applyOperation(5, 3, add));
        results.push('  applyOperation(5, 3, multiply) → ' + applyOperation(5, 3, multiply));
        results.push('  applyOperation(5, 3, (a, b) => a - b) → ' + applyOperation(5, 3, (a, b) => a - b));

        document.getElementById('output').textContent = results.join('\n');
    </script>

</body>
</html>

Quick Reference

Function Types

TypeSyntaxHoisted?this Binding
Declarationfunction name() { }✅ YesDynamic
Expressionconst name = function() { }❌ NoDynamic
Arrowconst name = () => { }❌ NoLexical

Parameters vs Arguments

TermDefinitionExample
ParametersNames in definitionfunction add(a, b)
ArgumentsValues passedadd(5, 3)

Default Arguments

SyntaxResult
function greet(name = "Guest") { }ES6 default
greet()Uses default
greet("Alice")Uses argument
greet(undefined)Uses default
greet(null)Uses null (NOT default!)

Return Values

SituationReturns
return value;That value
return;undefined
No returnundefined
return ends executionImmediately

Best Practices

Do This:

// Use descriptive function names
function calculateTotal(price, quantity) {
    return price * quantity;
}

// Use default parameters (ES6)
function greet(name = "Guest") {
    return `Hello, ${name}`;
}

// Use rest parameters for variable arguments
function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0);
}

// Return early for guard clauses
function checkAge(age) {
    if (age < 0) return "Invalid";
    if (age < 18) return "Minor";
    return "Adult";
}

// Use arrow functions for short callbacks
const doubled = [1, 2, 3].map(n => n * 2);

Don’t Do This:

// Don't use vague names
function x(a, b) { return a + b; }

// Don't forget to return
function add(a, b) {
    a + b; // Missing return! Returns undefined
}

// Don't use arguments object in arrow functions
const sum = () => {
    // arguments is not defined here!
};

// Don't use default parameter expressions with side effects
function greet(name = generateRandomName()) { } // Runs every call

// Don't rely on implicit defaults with ||
function greet(name) {
    name = name || "Guest"; // "" and 0 trigger default!
}

Common Pitfalls

PitfallProblemSolution
Missing returnFunction returns undefinedAdd return
Calling expression before definitionTypeErrorDefine before calling
null with defaultsDoesn’t trigger defaultUse ?? or explicit check
Arrow function thisLexical, not dynamicUse regular function if needed
Modifying parametersSide effectsCreate a local copy
Too many parametersHard to readUse an options object

Pro Tip: Use function declarations for named, reusable functions — they’re hoisted and easier to debug. Use arrow functions for short callbacks and when you want lexical this. Always return early for guard clauses to avoid deep nesting. Use default parameters (name = "Guest") instead of manual undefined checks — but remember: null does NOT trigger defaults, only undefined does. And for variable arguments, use rest parameters (...args) instead of the legacy arguments object — they’re cleaner and work in arrow functions!


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!