Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Functions in JavaScript

What is a Function?

A function in JavaScript is a reusable block of code designed to perform a specific task. Instead of writing the same logic multiple times, you define it once and call it whenever needed. Functions improve readability, reduce repetition, and make programs easier to maintain and test.

The basic syntax for defining and calling a function looks like this:

Basic Syntax
// Defining a function
function functionName(parameters) {
  // statements
}

// Calling a function
functionName();

// Simple example
function sayHello() {
  console.log('Hello World!');
}

sayHello(); // Hello World!

1. Function Declaration

A function declaration defines a named function using the function keyword. Function declarations are hoisted — the JavaScript engine moves them to the top of their scope, so you can call them before they appear in the code.

  • Hoisted to the top of their scope.
  • Can be called before the line where they are defined.
  • Supports default parameters and rest parameters.
Function Declaration
// Can be called before it is defined (hoisting)
console.log(greet('Alice')); // Hello, Alice!

function greet(name) {
  return `Hello, ${name}!`;
}

// Default parameter
function add(a, b = 0) {
  return a + b;
}
console.log(add(5));     // 5
console.log(add(5, 3));  // 8

// Rest parameters — collects remaining args into an array
function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

2. Function Expression

A function expression assigns a function to a variable. Unlike declarations, function expressions are not hoisted — you must define them before calling them. They can be anonymous (no name) or named.

Named function expressions are useful for recursion and produce clearer stack traces during debugging.

Function Expression
// Anonymous function expression
const multiply = function(a, b) {
  return a * b;
};
console.log(multiply(4, 5)); // 20

// Named function expression — name is only visible inside the function
const factorial = function fact(n) {
  return n <= 1 ? 1 : n * fact(n - 1);
};
console.log(factorial(5)); // 120

// Must be defined before calling (not hoisted)
// console.log(multiply(2, 3)); // ReferenceError if called before definition

3. Arrow Functions (ES6+)

Arrow functions provide a shorter syntax for writing functions. They are always anonymous and have two important differences from regular functions:

  • No own this — they inherit this from the enclosing scope (lexical this).
  • Cannot be used as constructors (no new).
  • Single-expression bodies have an implicit return — no need for return or curly braces.
Arrow Functions
// Single parameter — no parentheses needed
const square = n => n * n;
console.log(square(5)); // 25

// Multiple parameters — parentheses required
const add = (a, b) => a + b;
console.log(add(3, 4)); // 7

// Multi-line body — curly braces and explicit return required
const divide = (a, b) => {
  if (b === 0) throw new Error('Division by zero');
  return a / b;
};
console.log(divide(10, 2)); // 5

// Arrow functions shine in array methods
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);          // [2,4,6,8,10]
const evens   = numbers.filter(n => n % 2 === 0); // [2,4]
const total   = numbers.reduce((sum, n) => sum + n, 0); // 15

4. Higher-Order Functions

A higher-order function is a function that either takes another function as an argument, returns a function, or both. This is a core concept in functional programming and is the foundation of built-in methods like map(), filter(), and reduce().

Higher-Order Functions
// Takes a function as an argument
function applyTwice(fn, value) {
  return fn(fn(value));
}
const double = x => x * 2;
console.log(applyTwice(double, 3)); // 12

// Returns a function (function factory using closure)
function multiplier(factor) {
  return n => n * factor;
}
const triple = multiplier(3);
const times5 = multiplier(5);
console.log(triple(4)); // 12
console.log(times5(4)); // 20

// Callback pattern
function fetchData(url, onSuccess, onError) {
  setTimeout(() => {
    if (url) onSuccess({ data: 'result' });
    else onError(new Error('No URL provided'));
  }, 1000);
}
fetchData('/api/data', data => console.log(data), err => console.error(err));

5. IIFE — Immediately Invoked Function Expression

An IIFE is a function that is defined and called at the same time. It creates a private scope, preventing variables from leaking into the global scope. IIFEs were widely used before ES6 modules became standard.

IIFE
// Classic IIFE — runs immediately, creates private scope
(function() {
  const privateVar = 'I am private';
  console.log(privateVar); // I am private
})();

// console.log(privateVar); // ReferenceError — not accessible outside

// Arrow function IIFE
const result = (() => {
  const x = 10, y = 20;
  return x + y;
})();
console.log(result); // 30

Function Declaration vs Expression vs Arrow

Here is a quick comparison of the three main function types to help you choose the right one:

Comparison
// Declaration — hoisted, has own this, can be constructor
function Declaration(x) { return x; }

// Expression — not hoisted, has own this, can be constructor
const Expression = function(x) { return x; };

// Arrow — not hoisted, NO own this, NOT a constructor
const Arrow = x => x;

// When to use each:
// Declaration  → top-level utility functions, methods that need hoisting
// Expression   → callbacks stored in variables, conditional function assignment
// Arrow        → short callbacks, array methods, when you need lexical this
Key Takeaways
  • Function declarations are hoisted — they can be called before they appear in the code. Function expressions are NOT hoisted.
  • Arrow functions do not have their own this — they inherit it from the enclosing scope. Use regular functions when you need a dynamic this.
  • Default parameters (b = 0) handle missing arguments gracefully without needing manual checks.
  • Rest parameters (...args) collect all remaining arguments into an array — useful for variadic functions.
  • Higher-order functions take or return other functions — the foundation of map(), filter(), and reduce().
  • IIFEs create a private scope immediately — useful for isolating code and avoiding global variable pollution.

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.