JavaScript Defining Functions: Syntax, Examples, and Best Practices

Functions are one of the most important building blocks in JavaScript. This article shows you how to define them, how the main forms differ, and how to choose the right one for everyday code.

Quick answer: In JavaScript, you can define a function with a function declaration, a function expression, or an arrow function. All three create reusable code, but they differ in hoisting, naming, and how this behaves.

Difficulty: Beginner

You'll understand this better if you know: basic JavaScript variables, how to call a function, and the idea of returning a value from code.

1. What Is Defining Functions?

Defining a function means writing a reusable block of JavaScript code and giving it a name or storing it in a variable so you can run it later.

When people say they want to “create a function,” they usually mean writing the function’s definition, not just calling it.

2. Why Defining Functions Matters

Functions help you avoid repeating the same code. They also make programs easier to read, test, and update.

In real projects, functions are used to format data, validate forms, calculate totals, handle events, and break large problems into smaller pieces.

You should use functions whenever a task repeats, has a clear input and output, or deserves a named piece of logic.

3. Basic Syntax or Core Idea

There are three common ways to define a function in modern JavaScript. The simplest starting point is a function declaration.

Function declaration

A function declaration starts with the function keyword, followed by a name, parameters in parentheses, and a code block.

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

This defines a function named greet that takes one parameter, name, and returns a greeting string.

Function expression

You can also define a function by assigning it to a variable.

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

Here, the function is stored in greet. This is called a function expression.

Arrow function

Arrow functions provide shorter syntax for many cases.

const greet = (name) => {
  return `Hello, ${name}!`;
};

This version does the same job, but with a more compact form. It is especially common for callbacks and small utility functions.

4. Step-by-Step Examples

Example 1: A function that adds two numbers

This example shows the most basic pattern: take inputs, process them, and return a result.

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

const sum = add(3, 5);

The function definition makes add reusable. Calling it with 3 and 5 returns 8.

Example 2: A function with no parameters

A function does not need parameters if it always performs the same task.

function showWelcomeMessage() {
  return "Welcome to the dashboard.";
}

This is useful for fixed messages, setup code, or actions that do not depend on input.

Example 3: An arrow function with one expression

When the function body is a single expression, you can write a shorter arrow function.

const double = (n) => n * 2;

This returns the result directly without a separate return statement.

Example 4: A function that returns an object

When returning an object literal from an arrow function, wrap the object in parentheses.

const createUser = (name) => ({
  name: name,
  active: true
});

This pattern is common when building simple records or returning structured data from helper functions.

5. Practical Use Cases

Functions are especially useful when the same logic appears in more than one place.

6. Common Mistakes

Mistake 1: Forgetting to call the function

Defining a function does not run it. New developers often write the definition and expect output immediately.

Problem: The function exists, but nothing happens because it was never called.

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

sayHi;

Fix: Add parentheses to call the function.

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

sayHi();

The corrected version works because the function is actually executed.

Mistake 2: Using the wrong syntax for an arrow function body

Arrow functions need curly braces when you want multiple statements. If you use braces, you must write return explicitly.

Problem: This function has a block body but no return statement, so it returns undefined.

const getTotal = (price, tax) => {
  price + tax;
};

Fix: Return the value explicitly, or remove the braces for a single expression.

const getTotal = (price, tax) => {
  return price + tax;
};

The fixed version returns the computed total as expected.

Mistake 3: Calling a function before a function expression is initialized

Function declarations are hoisted, but function expressions assigned to variables are not available before the variable is initialized.

Problem: This can cause a runtime error such as Cannot access 'hello' before initialization when using const or let.

hello();

const hello = function() {
  return "Hello";
};

Fix: Define the variable before calling it, or use a function declaration if early access is needed.

const hello = function() {
  return "Hello";
};

hello();

The corrected version works because the function is initialized before use.

7. Best Practices

Practice 1: Use descriptive names

Name functions for what they do, not how they are implemented. Clear names make code easier to scan and maintain.

function calculateShippingCost(weight) {
  return weight * 2.5;
}

This is better than a vague name like doThing because the purpose is obvious.

Practice 2: Return values instead of printing when possible

A function is more reusable when it returns data instead of directly logging it.

function formatName(first, last) {
  return `${first} ${last}`;
}

This approach lets other code decide whether to display, store, or reuse the result.

Practice 3: Keep one clear responsibility per function

Smaller functions are easier to test and change than large ones that do too much.

function isEligible(age) {
  return age >= 18;
}

This function only checks eligibility, which makes its purpose obvious and its behavior predictable.

8. Limitations and Edge Cases

A common “not working” report is “my function returns undefined.” In many cases, the function runs correctly but never reaches a return statement.

9. Practical Mini Project

Let’s build a small discount calculator using function definitions. The example combines a declaration, a helper function, and a function expression.

function calculateDiscountedPrice(price, discountPercent) {
  const discountAmount = price * (discountPercent / 100);
  return price - discountAmount;
}

const formatCurrency = function(value) {
  return `${value.toFixed(2)}`;
};

const originalPrice = 120;
const finalPrice = calculateDiscountedPrice(originalPrice, 15);

console.log(formatCurrency(finalPrice));

This mini project shows how one function can calculate a result and another can present it. That separation makes the code easier to extend later.

10. Key Points

11. Practice Exercise

Write a function-based utility that helps a bookstore calculate the total price of a cart.

Expected output: For [10, 15, 25], the total should be 50, and the formatted result should look like $50.00.

Hint: Use a loop or reduce for the total, and toFixed(2) for formatting.

Solution:

function calculateCartTotal(prices) {
  let total = 0;

  for (const price of prices) {
    total += price;
  }

  return total;
}

function formatTotal(amount) {
  return `${amount.toFixed(2)}`;
}

const prices = [10, 15, 25];
const total = calculateCartTotal(prices);
const displayTotal = formatTotal(total);

12. Final Summary

Defining functions is how you turn repeated logic into reusable JavaScript code. Once you understand declarations, expressions, and arrow functions, you can read most function definitions you see in real projects.

As you practice, focus on choosing the form that best matches the situation. Use function declarations when hoisting and readability are helpful, use expressions when you want a value stored in a variable, and use arrow functions for compact callbacks and small helpers.

If you want to keep learning, the next natural topic is how to call functions with parameters and how return values move data through your program.