JavaScript Functions

A function is a reusable block of code for a specific task. Instead of writing the same logic again and again, you write it once and call it whenever you need it.

Functions keep your code organized and easier to maintain. They can take inputs (called parameters), run logic, and optionally return a result.

JavaScript basic functions

javascript

function formatPrice(amount) {
  return "$" + amount.toFixed(2);
}

console.log(formatPrice(9.99)); // $9.99
console.log(formatPrice(24.5)); // $24.50

Key points about functions:

  • Defined once, called many times.
  • Can accept zero or more parameters.
  • Can return a value using the return keyword.
  • If no return is used, the function returns undefined.

JavaScript supports several ways to define functions. Each has slightly different behavior and syntax:

  • Function Declaration: uses the function keyword with a name.
  • Function Expression: assigns a function to a variable.
  • Arrow Function: a shorter syntax introduced in ES6.
  • Anonymous Function: a function without a name, often used inline.
  • IIFE (Immediately Invoked Function Expression) - runs right after it is defined.
JavaScript different types of functions

javascript

// Function Declaration
function sayHi() { console.log("Hi!"); }

// Function Expression
const sayHello = function() { console.log("Hello!"); };

// Arrow Function
const sayHey = () => console.log("Hey!");

// IIFE
(function() { console.log("I run immediately!"); })();

A function declaration is the most common way to create a function in JavaScript. It is written using the function keyword followed by a function name. Once created, you can call the function whenever you need to reuse the same block of code.

One of the biggest advantages of a function declaration is hoisting. JavaScript moves the function declaration to the top of its scope during execution. Because of this, you can call the function even before it appears in your code, and it will still work correctly.

Function declarations are easy to read, reusable, and widely used in JavaScript projects. They are a great choice whenever you want to organize your code into clear, reusable functions.

JavaScript function declarations

javascript

// Called before it is defined - works due to hoisting
console.log(add(2, 3)); // 5

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

Function declarations are fully hoisted to the top of their scope, so they are available throughout the entire scope they belong to.

Tip: If you call a function before it is defined, function declarations work because of hoisting, but function expressions do not.

A function expression is created by assigning a function to a variable. Instead of giving the function a direct name, the function becomes the value of the variable. You can then use that variable name to call the function whenever needed.

Unlike function declarations, function expressions are not hoisted. This means JavaScript does not make them available before the line where they are defined. If you try to call a function expression before its definition, you will get an error.

Function expressions are useful when you want to store functions in variables, pass them as arguments, or use them as callbacks. They are widely used in modern JavaScript and help make your code more flexible and organized.

JavaScript function expression

javascript

// Cannot call before definition
// console.log(multiply(2, 3)); // TypeError: multiply is not a function

const multiply = function(a, b) {
  return a * b;
};

console.log(multiply(2, 3)); // 6

Function expressions are useful when you want to pass a function as an argument, return it from another function, or control exactly when a function is created.

Arrow functions are a shorter and cleaner way to write functions in JavaScript. They were introduced in ES6 (ECMAScript 2015) and use the => syntax, making your code easier to read and write, especially for simple functions.

Unlike regular functions, arrow functions have a shorter syntax and do not require the function keyword. They are commonly used for callbacks, array methods like map(), filter(), and forEach(), as well as event handlers where a compact syntax is preferred.

Arrow functions are always anonymous, meaning they do not have their own function name unless they are assigned to a variable. They also handle this differently from regular functions, which makes them very useful in modern JavaScript applications.

JavaScript arrow function

javascript

// Regular function
const double = function(n) { return n * 2; };

// Arrow function - same thing, shorter syntax
const doubleArrow = (n) => n * 2;

console.log(double(5));      // 10
console.log(doubleArrow(5)); // 10

Key differences of arrow functions:

  • Do not have their own this: they inherit this from the surrounding scope.
  • Cannot be used as constructors (no new keyword).
  • Do not have an arguments object.
  • Cannot use super.
  • Support implicit return when there are no curly braces block.

An anonymous function is a function that does not have a name. Instead of giving it a name, you create and use it directly where it is needed. Anonymous functions are commonly used for short tasks that only need to run once.

They are often used as callbacks, event handlers, or assigned to variables. For example, methods like setTimeout(), setInterval(), forEach(), and map() frequently use anonymous functions because they make the code shorter and easier to understand.

Both function expressions and arrow functions are usually anonymous unless they are assigned to a variable. They are widely used in modern JavaScript because they help write clean, readable, and reusable code.

JavaScript anonymous function

javascript

// Anonymous function as a callback
setTimeout(function() {
  console.log("Runs after 1 second");
}, 1000);

// Anonymous arrow function as a callback
[1, 2, 3].forEach(n => console.log(n));

Anonymous functions are common in event handlers, array methods like map, filter, and reduce, and anywhere a function is used only once.

The key differences between a function declaration and a function expression are:

  • Hoisting: Function declarations are hoisted; function expressions are not.
  • Name: Declarations always have a name; expressions can be anonymous.
  • Usage: Declarations are statements; expressions are values you can assign or pass around.
JavaScript function declaration vs function expression

javascript

// Declaration - hoisted, works before definition
console.log(square(4)); // 16
function square(n) { return n * n; }

// Expression - NOT hoisted
// console.log(cube(3)); // TypeError
const cube = function(n) { return n * n * n; };
console.log(cube(3)); // 27

Both function expressions and arrow functions can be stored in variables and called in the same way. They are commonly used when you want to pass a function as a callback, assign it to a variable, or keep your code more flexible.

Although they look similar, they are not exactly the same. Arrow functions have a shorter syntax and automatically inherit the this value from their surrounding scope. Function expressions, on the other hand, have their own this value and behave more like traditional JavaScript functions.

Knowing the difference between them helps you choose the right type of function for different situations. For simple callbacks and array methods, arrow functions are usually preferred, while function expressions are useful when you need the behavior of a regular function.

JavaScript function expressions and arrow functions

Syntax

javascript

// Function expression
const greet = function(name) {
  return "Hello, " + name;
};

// Arrow function - same result
const greetArrow = (name) => "Hello, " + name;

this

javascript

const obj = {
  name: "JS",
  // function expression has its own 'this'
  regularFn: function() { console.log(this.name); }, // "JS"
  // arrow function inherits 'this' from outer scope
  arrowFn: () => { console.log(this); } // undefined or window
};

obj.regularFn(); // JS
obj.arrowFn();   // undefined (arrow does not bind 'this')

arguments object

javascript

const regularFn = function() {
  console.log(arguments); // works
};

const arrowFn = () => {
  console.log(arguments); // ReferenceError: arguments is not defined
};

regularFn(1, 2, 3);

new keyword

javascript

const Fn = function() { this.value = 42; };
const obj1 = new Fn(); // works fine

const ArrowFn = () => {};
const obj2 = new ArrowFn(); // TypeError: ArrowFn is not a constructor

super

javascript

class Animal {
  speak() { return "..."; }
}

class Dog extends Animal {
  speak() {
    // regular method can use super
    return super.speak() + " Woof!";
  }
}

console.log(new Dog().speak()); // ... Woof!

Arrow functions cannot use super because they do not have their own this binding. Use regular methods in classes when you need super.

Implicit return

javascript

// Arrow function with implicit return (no braces, no return keyword)
const add = (a, b) => a + b;
console.log(add(3, 4)); // 7

// Returning an object - wrap in parentheses
const makeObj = (x) => ({ value: x });
console.log(makeObj(10)); // { value: 10 }

When an arrow function body has no curly braces, the expression is automatically returned. This is called implicit return. To return an object literal, wrap it in parentheses to avoid confusion with a block.

Rule of thumb: Use arrow functions for small callbacks and utility functions. Use regular functions when you need this, arguments, or constructor behavior.

Creating a function only defines what it should do. The code inside the function does not run automatically. To execute the function, you need to call (or invoke) it by writing its name followed by parentheses ().

Every time you call a function, JavaScript runs the code inside it. You can call the same function as many times as you want, which helps you reuse code instead of writing the same logic again and again.

If the function accepts parameters, you can pass values inside the parentheses when calling it. These values are called arguments and allow the function to produce different results for different inputs.

JavaScript function invoking

javascript

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

sayHello(); // Invokes the function -> Output: Hello!

Functions can also be called from inside other functions:

javascript

function notifyUser(orderId) {
  const message = buildNotification(orderId);
  console.log(message);
}

function buildNotification(orderId) {
  return "Order " + orderId + " shipped!";
}

notifyUser("ORD-7890"); // Order ORD-7890 shipped!

Parameters are the variable names written inside the parentheses when a function is created. They act as placeholders that tell the function what kind of values it can receive when it is called.

Arguments are the actual values you pass to the function when calling it. JavaScript takes these values and assigns them to the corresponding parameters, allowing the function to work with different inputs each time it runs.

In simple words, parameters are the variables in the function definition, while arguments are the real values you provide when the function is called. This makes functions flexible, reusable, and capable of producing different results with different inputs.

JavaScript parameters and arguments

javascript

// 'a' and 'b' are parameters
function add(a, b) {
  return a + b;
}

// 3 and 5 are arguments
console.log(add(3, 5)); // 8

If you pass fewer arguments than parameters, the missing ones are undefined. If you pass more, the extras are simply ignored (unless you use the arguments object or rest parameters).

Inside a regular JavaScript function, there is a special array-like object called arguments. It automatically stores all the values passed to the function, even if you do not define parameters for them.

The arguments object lets you access each argument by its index and find out how many arguments were passed. This is useful when a function can receive a different number of values every time it is called.

Keep in mind that the arguments object is available only inside regular functions. It does not exist in arrow functions. In modern JavaScript, the rest parameter (...args) is usually preferred because it provides a real array and is easier to work with.

JavaScript arguments object

javascript

function sum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}

console.log(sum(1, 2, 3));       // 6
console.log(sum(10, 20, 30, 40)); // 100

arguments is array-like but not a real array. You can convert it to an array using Array.from(arguments) or the spread operator [...arguments]. In modern code, prefer using rest parameters instead.

Default parameters allow you to assign a default value to a function parameter. If no argument is passed, or the argument is undefined, JavaScript automatically uses the default value instead. This feature was introduced in ES6.

Default parameters make functions more flexible and prevent errors caused by missing values. Instead of checking whether an argument exists, you can define a fallback value directly in the function declaration, making your code cleaner and easier to read.

They are commonly used for optional settings, default options, and values that should be used when the caller does not provide an argument. This helps you write more reliable and reusable JavaScript functions.

JavaScript default parameters

javascript

function greet(role = "viewer") {
  return "Access granted: " + role;
}

console.log(greet("admin")); // Access granted: admin
console.log(greet());        // Access granted: viewer

You can use any expression as a default value, including another function call or another parameter:

javascript

function multiply(a, b = a * 2) {
  return a * b;
}

console.log(multiply(3));    // 3 * 6 = 18
console.log(multiply(3, 4)); // 3 * 4 = 12

In JavaScript, how arguments behave inside a function depends on whether the value is a primitive or an object:

  • Primitives (numbers, strings, booleans) are passed by value. A copy is made, so changes inside the function do not affect the original.
  • Objects and arrays are passed by reference. The function receives a reference to the same object, so changes inside the function affect the original.
JavaScript passing arguments

Passing by value (primitives)

javascript

function addTen(num) {
  num += 10; // changes local copy only
  console.log("Inside:", num); // Inside: 15
}

let x = 5;
addTen(x);
console.log("Outside:", x); // Outside: 5 (unchanged)

Passing by reference (objects)

javascript

function updateStatus(order) {
  order.status = "shipped"; // modifies the original object
}

const order = { status: "pending" };
updateStatus(order);
console.log(order.status); // shipped (changed!)

To avoid accidentally mutating objects, create a copy before modifying them inside a function using the spread operator or Object.assign.

  • Function: a reusable block of code that performs a task.
  • Function declaration: hoisted; can be called before its definition.
  • Function expression: not hoisted; assigned to a variable.
  • Arrow function: concise syntax; no own this, arguments, or new.
  • Anonymous function: a function with no name, used inline or as a callback.
  • Parameters: named variables in the function definition that receive the values passed in when the function is called.
  • Arguments: actual values passed when calling a function.
  • arguments object: available in regular functions; holds all passed arguments.
  • Default parameters: provide fallback values for missing arguments.
  • Pass by value: primitives are copied; changes inside the function do not affect the original.
  • Pass by reference: objects are shared; changes inside the function affect the original.

What's next? Now that you know how functions work, let's move on to arrays in the next tutorial.

Videos for this topic will be added soon.

Reviewed by

SimplyJavaScript Editorial Team

Technical editors and JavaScript educators with hands-on experience building frontend projects, writing learning material, and reviewing tutorials for clarity, accuracy, and beginner-friendly guidance.