Docs

README

5.1 Function Declarations

Overview

Functions are the fundamental building blocks of JavaScript applications. A function declaration is one of the primary ways to define a reusable block of code that performs a specific task. Function declarations are hoisted, meaning they can be called before they appear in the code.


Table of Contents

  1. •What is a Function?
  2. •Function Declaration Syntax
  3. •Calling Functions
  4. •Parameters and Arguments
  5. •Return Statement
  6. •Hoisting
  7. •Function Naming Conventions
  8. •Scope Inside Functions
  9. •Function as First-Class Citizens
  10. •Best Practices

What is a Function?

A function is a reusable block of code designed to perform a particular task.

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                      Function Anatomy                    │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                          │
│  function greet(name) {                                  │
│  ────────  ─────  ────                                   │
│  keyword   name   parameters                             │
│                                                          │
│      return "Hello, " + name;                            │
│      ──────  ────────────────                            │
│      return  return value                                │
│  }                                                       │
│                                                          │
│  greet("World");   // Call the function                  │
│                                                          │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Why Use Functions?

BenefitDescription
ReusabilityWrite once, use many times
ModularityBreak code into manageable pieces
AbstractionHide complexity behind simple interfaces
MaintainabilityEasier to update and debug
TestingFunctions can be tested in isolation

Function Declaration Syntax

Basic Syntax

function functionName(parameters) {
  // Function body
  // Code to execute
  return value; // Optional
}

Examples

// Simple function with no parameters
function sayHello() {
  console.log('Hello!');
}

// Function with one parameter
function greet(name) {
  console.log('Hello, ' + name + '!');
}

// Function with multiple parameters
function add(a, b) {
  return a + b;
}

// Function with no return (returns undefined)
function logMessage(message) {
  console.log(message);
}

Calling Functions

To execute a function, you call (or invoke) it using its name followed by parentheses.

// Define
function greet(name) {
  return 'Hello, ' + name;
}

// Call
greet('Alice'); // "Hello, Alice"
greet('Bob'); // "Hello, Bob"

// Store result
const message = greet('Charlie');
console.log(message); // "Hello, Charlie"

// Use in expressions
console.log(greet('Dave').toUpperCase()); // "HELLO, DAVE"

Function Call vs Function Reference

function sayHi() {
  return 'Hi!';
}

sayHi(); // "Hi!" - Calls the function
sayHi; // [Function: sayHi] - Reference to function

Parameters and Arguments

Parameters

Variables listed in the function definition.

Arguments

Actual values passed when calling the function.

function multiply(a, b) {
  // a, b are parameters
  return a * b;
}

multiply(3, 4); // 3, 4 are arguments

Default Parameters

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

greet(); // "Hello, Guest"
greet('Alice'); // "Hello, Alice"

Multiple Parameters

function createUser(name, age, city = 'Unknown') {
  return {
    name: name,
    age: age,
    city: city,
  };
}

createUser('John', 25, 'NYC');
createUser('Jane', 30); // city defaults to "Unknown"

Rest Parameters

function sum(...numbers) {
  let total = 0;
  for (const num of numbers) {
    total += num;
  }
  return total;
}

sum(1, 2, 3); // 6
sum(1, 2, 3, 4, 5); // 15

Return Statement

The return statement specifies the value returned by the function.

// With return
function square(x) {
  return x * x;
}
console.log(square(5)); // 25

// Without return (returns undefined)
function log(message) {
  console.log(message);
}
console.log(log('Hi')); // undefined

Early Return

function absoluteValue(num) {
  if (num < 0) {
    return -num; // Early return
  }
  return num;
}

// Guard clause pattern
function processUser(user) {
  if (!user) {
    return null; // Guard clause
  }
  // Main logic
  return { ...user, processed: true };
}

Returning Multiple Values

// Return an array
function minMax(numbers) {
  return [Math.min(...numbers), Math.max(...numbers)];
}
const [min, max] = minMax([3, 1, 4, 1, 5, 9]);

// Return an object
function getUserInfo() {
  return {
    name: 'Alice',
    age: 25,
    email: 'alice@example.com',
  };
}
const { name, email } = getUserInfo();

Hoisting

Function declarations are hoisted to the top of their scope, meaning you can call them before they appear in the code.

// This works!
greet('Alice'); // "Hello, Alice"

function greet(name) {
  console.log('Hello, ' + name);
}

Hoisting Visualization

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    Hoisting Process                      │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                          │
│  What you write:                What JavaScript sees:    │
│  ──────────────                 ────────────────────     │
│                                                          │
│  sayHi();                       function sayHi() {       │
│                                     return "Hi!";        │
│  function sayHi() {             }                        │
│      return "Hi!";                                       │
│  }                              sayHi();                 │
│                                                          │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Hoisting vs Function Expressions

// Function declaration - hoisted
greet(); // Works!
function greet() {
  console.log('Hi');
}

// Function expression - NOT hoisted
// sayBye();  // Error: sayBye is not a function
const sayBye = function () {
  console.log('Bye');
};
sayBye(); // Works after definition

Function Naming Conventions

Best Practices

PatternUsageExample
Verb + NounActionsgetUserData(), calculateTotal()
is/has/canBoolean returnsisValid(), hasPermission()
get/setGetters/SettersgetName(), setAge()
handle/onEvent handlershandleClick(), onSubmit()
create/buildFactory functionscreateUser(), buildConfig()
validate/checkValidationvalidateEmail(), checkInput()

Examples

// Action functions
function fetchUserData(userId) {}
function sendEmail(to, subject, body) {}
function calculateTax(amount, rate) {}

// Boolean functions
function isValidEmail(email) {
  return email.includes('@');
}
function hasPermission(user, action) {
  return user.permissions.includes(action);
}

// Getter/Setter style
function getUserName(user) {
  return user.firstName + ' ' + user.lastName;
}

// Event handlers
function handleButtonClick(event) {}
function onFormSubmit(data) {}

Scope Inside Functions

Functions create their own scope. Variables declared inside are not accessible outside.

function createGreeting() {
  const greeting = 'Hello'; // Local variable
  return greeting;
}

createGreeting();
// console.log(greeting);  // Error: greeting is not defined

Accessing Outer Scope (Closure)

const prefix = 'Mr. ';

function greet(name) {
  // Can access prefix from outer scope
  return prefix + name;
}

greet('Smith'); // "Mr. Smith"

Parameter Scope

function example(x) {
  console.log(x); // Parameter is in local scope
  const x = 10; // Error: x already declared
}

Functions as First-Class Citizens

In JavaScript, functions are values. They can be:

1. Assigned to Variables

const myFunc = function greet() {
  return 'Hi';
};

2. Passed as Arguments

function executeCallback(callback) {
  return callback();
}

function sayHello() {
  return 'Hello!';
}

executeCallback(sayHello); // "Hello!"

3. Returned from Functions

function createMultiplier(factor) {
  return function (number) {
    return number * factor;
  };
}

const double = createMultiplier(2);
double(5); // 10

4. Stored in Data Structures

const operations = {
  add: function (a, b) {
    return a + b;
  },
  subtract: function (a, b) {
    return a - b;
  },
};

operations.add(5, 3); // 8
operations.subtract(5, 3); // 2

Best Practices

1. Single Responsibility

// āŒ Does too much
function processOrder(order) {
  // validate
  // save to database
  // send email
  // update inventory
}

// āœ… Single purpose
function validateOrder(order) {}
function saveOrder(order) {}
function sendConfirmation(order) {}
function updateInventory(order) {}

2. Keep Functions Small

// āŒ Too long
function doEverything() {
  // 100+ lines of code
}

// āœ… Small, focused functions
function step1() {}
function step2() {}
function step3() {}

3. Use Descriptive Names

// āŒ Unclear
function proc(d) {}
function x(a, b) {}

// āœ… Descriptive
function processUserData(data) {}
function calculateTotal(items, taxRate) {}

4. Limit Parameters

// āŒ Too many parameters
function createUser(name, age, email, address, phone, role) {}

// āœ… Use an options object
function createUser(options) {
  const { name, age, email, address, phone, role } = options;
}

// āœ… Or destructuring in parameters
function createUser({
  name,
  age,
  email,
  address = '',
  phone = '',
  role = 'user',
}) {}

5. Pure Functions When Possible

// āŒ Impure - modifies external state
let total = 0;
function addToTotal(amount) {
  total += amount;
}

// āœ… Pure - no side effects
function add(a, b) {
  return a + b;
}

6. Early Returns for Readability

// āŒ Nested conditionals
function getDiscount(user) {
  if (user) {
    if (user.isPremium) {
      if (user.yearsActive > 5) {
        return 0.3;
      } else {
        return 0.2;
      }
    } else {
      return 0.1;
    }
  }
  return 0;
}

// āœ… Early returns
function getDiscount(user) {
  if (!user) return 0;
  if (!user.isPremium) return 0.1;
  if (user.yearsActive > 5) return 0.3;
  return 0.2;
}

Summary

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│            Function Declarations Quick Reference         │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                          │
│  // Basic syntax                                         │
│  function name(params) {                                 │
│      return value;                                       │
│  }                                                       │
│                                                          │
│  // Key features:                                        │
│  • Hoisted (can call before definition)                  │
│  • Create own scope                                      │
│  • First-class citizens (values)                         │
│  • Can have default parameters                           │
│  • Can use rest parameters (...args)                     │
│                                                          │
│  // Naming conventions:                                  │
│  • verb + noun: calculateTotal()                         │
│  • is/has: isValid(), hasItems()                         │
│  • get/set: getName(), setAge()                          │
│  • handle/on: handleClick()                              │
│                                                          │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Next Steps

  • •Practice with the examples in examples.js
  • •Complete the exercises in exercises.js
  • •Learn about function expressions in the next topic
  • •Explore arrow functions and their syntax
README - JavaScript Tutorial | DeepML