Getting Comfortable with JavaScript Functions: From First Call to Return Value

Sangy KSangy K
15 min read

By now, we've explored variables, data types, operators, and control flow. But as our projects grow, we start to notice something: the same code keeps popping up everywhere.

This is where functions swoop in like our coding superheroes. ๐Ÿฆธโ€โ™€๏ธ

A function is a reusable, selfโ€‘contained block of code that we can call anytime to perform a specific task. Write it once, and reuse it endlessly.

No more copying and pasting the same calculations, the same checks, the same messages. With functions, whenever we need to update the logic, we make the change in one place, and it's reflected everywhere. What a relief! ๐Ÿ˜ฎโ€๐Ÿ’จ

Think of it like a recipe card โ€” you jot down the steps for making your favourite dish once, and anytime you want it, you just follow the card โ€” no need to reinvent the wheel (or the meal).

In this guide, we'll dive deep into Javascript functions: what they are, why they matter, and how to use them effectively. By the end, you'll confidently structure your code into neat, reusable blocks that make your programs cleaner, smarter, and easier to maintain.

What Is a Function?

A function in Javascript is a named and reusable block of code designed to perform a single, specific task.

We define it once and call it whenever we need to accomplish that task.

Imagine you're running a coffee shop. Every time someone orders a latte, you don't manually figure out how to make it from scratch. You have a "Make Latte" recipe:

  1. Steam milk

  2. Brew espresso

  3. Combine and serve

In code, that recipe would look like this:

function makeLatte() {
    console.log("Steaming milk...");
    console.log("Brewing espresso...");
    console.log("Latte ready! โ˜•");
}

Now, whenever a customer orders, we simply call makeLatte() and let our "assistant" handle the rest.

Why Use Functions?

  • DRY Code: Keep your code "Don't Repeat Yourself."

  • Organisation: Break big problems into smaller, manageable pieces and group related steps together.

  • Reusability: Write code once, use it everywhere. Also, makes debugging easier.

  • Readability: Makes our programs less intimidating and easier to understand.

Functions are the building blocks of clean and maintainable Javascript. They help us avoid copying and pasting the same code, keep things organised and make our programs easier to read and debug.

Functions Are First-Class Citizens

In Javascript, functions are first-class citizens. This means they behave like any other value:

  • We can store them in variables.

  • We can pass them as arguments to other functions.

  • We can return them from other functions.

This flexibility makes Javascript incredibly powerful. We will explore this later in the article. But for now, let's start with the basics: how to declare and use functions.

Declaring and Calling Functions

Declaring/Defining a Function - The classic way

The most common way to declare a function is with the function keyword:

function greet() {
  console.log("Hello, world!");
}
  • function โ†’ keyword to define a function.

  • greet โ†’ function's name.

  • () โ†’ parentheses for inputs (parameters). Empty here.

  • {} โ†’ the block of code that runs when we call the function.

We've now defined the function, but nothing happens yet. Javascript only executes it when we call it.

Calling (Invoking) a Function

To execute the function, we "call" it by writing its name followed by parentheses (). Each call runs the code inside the function. Call it again, and it runs again.

greet(); // Output: Hello, world!

Calling without () doesn't execute it; it just gives you the function definition:

console.log(greet); // Logs the function definition

Output:

Think of () as the "go" button โ€” forget them, and the machine just sits there.

Gotcha: Beginners often miss the (), wondering why nothing happens. Functions won't run until you call them.

Naming Functions

A good name makes your function's purpose obvious:

  • Use descriptive names and verbs: calculateTotal(), sendEmail(), formatDate().

  • Avoid vague names: doStuff(), thing() or foo().

  • Stick to camelCase for consistency: getUserData.

  • Avoid reserved keywords for names (`function`, return, etc.).

Hoisting Behavior

Here's a Javascript quirk: function declarations are hoisted. This means we can call a function before it's defined in the code.

In simpler terms, during the creation phase of the code(๐Ÿค” more on this later!), Javascript "lifts" function declarations to the top of their scope before execution, allowing us to call a function even before it's physically written in the code.

sayHi(); // "Hi!"

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

Javascript "lifts" function declarations to the top of their scope during execution.

Gotcha: This only works for declarations, not for function expressions (we'll explore scoping, hoisting and all those later).

Real-Life Example

Suppose we're building an app that welcomes users. Instead of writing a welcome message for each user, we can create a function that takes the user's name as an argument and generates a personalised welcome message. This function can be reused for every user, saving us from copying and pasting the same message for each user.

console.log("Welcome, Alex!");
console.log("Welcome, Luna!");
console.log("Welcome, Marco!");

We can create one function:


function welcomeUser(name) {
    console.log(`Welcome, ${name}!`);
}

welcomeUser("Alex");
welcomeUser("Luna");
welcomeUser("Marco");

Now, we just call welcomeUser() with different names. One function, many uses โ€” no more copying and pasting the same message. ๐ŸŽฏ

Function Parameters and Arguments

Sometimes we want our functions to adapt, like a vending machine that serves different drinks.

Parameters vs. Arguments

What are Parameters? ๐ŸŽฏ

A parameter is like a placeholder โ€” a named variable listed in the function definition.

When we declare a function, we usually don't yet know exactly what value we'll work with. So, we give it a placeholder.

Example:

function greet(name) {
  console.log(`Hello, ${name}!`);
}

Here:

  • name is the parameter.

  • We're saying: "This function expects a value called name when you run it."

What are Arguments? ๐Ÿงฉ

Arguments are the actual values we give to the function when we call it. They replace the parameters and make the function do something specific.

greet("Luna");
greet("Marco");

Here:

  • "Luna" and "Marco" are the arguments.

  • They replace the name parameter and personalise the greeting.

Output:

Hello, Luna!
Hello, Marco!

You Can Use Different Arguments Each Time ๐Ÿงช

The beauty of parameters and arguments is that we can reuse the same function for different values. That's what makes functions powerful and flexible.

function welcome(city) {
  console.log(`Welcome to ${city}!`);
}

welcome("Tokyo"); // Welcome to Tokyo!
welcome("Delhi"); // Welcome to Delhi!
welcome("Paris"); // Welcome to Paris!

Takeaway: The function stays the same, but the output changes depending on the argument.

This separation between definition (parameter) and usage (argument) is what allows functions to be reused.

Without parameters, every function would be locked to one fixed task.

Compare:

// Without parameters:
function greetLuna() {
  console.log("Hello, Luna!");
}

greetLuna();

// With parameters (reusable):
function greet(name) {
  console.log(`Hello, ${name}!`);
}

greet("Luna");
greet("Alex");

The second approach is better in every way โ€” shorter code, easier maintenance, and scalable logic.

โš ๏ธ Gotchas: What Happens if...

You pass fewer arguments than parameters?

The missing ones become undefined.

function showInfo(name, age) {
  console.log(`${name} is ${age} years old.`);
}

showInfo("Leo"); // Output: Leo is undefined years old.

You pass more arguments than parameters?

Javascript ignores the extras (unless you handle them via rest parameters).

function showCity(city) {
  console.log(`City: ${city}`);
}

showCity("Berlin", "Extra"); // Only "Berlin" is used.

๐Ÿง  Best Practices

  • Name your parameters clearly ๐Ÿท: Use userName, price, email, not x or val.

  • Keep it simple ๐Ÿ”ข: Start with 1โ€“2 parameters before moving to advanced patterns.`

  • Never confuse console.log() and return ๐Ÿ“ฅ โ€”we'll talk more about that soon!

  • Use default parameters ๐Ÿงผ to handle missing arguments gracefully.

Want to handle unlimited arguments? That's what rest parameters (...args) are for โ€” and we'll explore that soon! ๐Ÿ‘€

Multiple Arguments: More Than Just One Input ๐Ÿ‘ซ

So far, we've seen functions that take a single input โ€” like a person's name or a city name.

But in the real world, tasks often require multiple pieces of information.

In Javascript, you can define functions that accept more than one parameter.

function introduce(name, age) {
  console.log(`My name is ${name} and I'm ${age} years old.`);
}

introduce("SK", 25);
introduce("Jane", 30);

Here, name and age are parameters; "SK" and 25 are the arguments.

While you can pass many arguments, don't overdo it. If a function requires 6 or 7 arguments, it becomes:

  • ๐Ÿ” Hard to read.

  • ๐Ÿ”ข Easy to mix up argument order.

  • ๐Ÿง  Harder to remember and maintain.

function createUser(name, age, email, phone, address, occupation, isActive){ 
    // ... 
}

Too much to remember, right?

Instead of passing arguments one by one, pass them inside an object.

function createUser(user) {
  console.log(`Name: ${user.name}, Age: ${user.age}, Email: ${user.email}`);
}

createUser({
  name: "Luna",
  age: 28,
  email: "luna@example.com"
});

This:

  • Makes the function easier to understand.

  • Makes arguments optional and flexible.

  • It is easier to maintain as your function grows.

We'll dive deeper into this object pattern later in the series (mainly when we cover objects and destructuring).

Default Parameters

In real life, we often deal with defaults:

  • Can't find your name tag? Here's one labelled "Guest."

  • No input in a form field? Use a placeholder.

Javascript functions can do the same thing with default parameters โ€” values that are used automatically if the caller doesn't provide them.

Let's say we define this function:

function greet(name) {
  console.log(`Hello, ${name}!`);
}

And we call it like this:

greet("Alex"); // โœ… Works great
greet(); // ๐Ÿ˜ฌ Hello, undefined!

Oops! We forgot to pass an argument the second time, and the name became undefined.

This is where default parameters shine โœจ

To Fix: Use a Default Parameter ๐ŸŒŸ

function greet(name = "Guest") {
  console.log(`Hello, ${name}!`);
}

greet("Alex"); // Hello, Alex!
greet(); // Hello, Guest!

Boom ๐Ÿ’ฅ โ€” now our function is safer and more user-friendly!

When a function is called without an argument, Javascript

  1. Checks if a default value is specified.

  2. If so, it uses that value instead of undefined.

function welcome(user = "Stranger") {
  console.log(`Welcome, ${user}`);
}

welcome(); // Welcome, Stranger
welcome("Charlotte"); // Welcome, Charlotte

โš ๏ธ Gotcha: Defaults Only Trigger on undefined

Be careful โ€” default parameters only apply when the argument is undefined.

function showMessage(message = "No message provided") {
  console.log(message);
}

showMessage(); // "No message provided"
showMessage(undefined); // "No message provided"
showMessage(null); // null ๐Ÿ˜ฌ
showMessage(""); // "" (empty string)

null, "" (empty string), 0, and false will NOT trigger the default.

โš ๏ธ Gotcha: Put Required Parameters First, Defaults Last

When using default parameters, always place required parameters before optional/default ones.

Why? ๐Ÿง 

Because Javascript fills parameters positionally โ€” left to right โ€” and if you mix the order, things get messy fast.

function createUser(role = "guest", name) {
  console.log(`${name} is a ${role}`);
}

createUser("Alice"); // โŒ name becomes "Alice", role is "guest"

Oops! We only passed one argument, and it went to the first parameter (role). But that's not what we intended โ€” we wanted "Alice" to be the name.

function createUser(name, role = "guest") {
  console.log(`${name} is a ${role}`);
}

createUser("Alice"); // โœ… Alice is a guest
createUser("Bob", "admin"); // โœ… Bob is a admin

This way:

  • name is required.

  • role is optional and has a fallback.

โœจ Always Remember,

  • Define required parameters first.

  • Follow with optional/default parameters.

  • This keeps function calls predictable and readable.

Rest Parameters: Handling Unlimited Arguments ๐Ÿ“ฆ

Sometimes we build functions that should accept any number of inputs โ€” not just one or two. Think of a calculator that can add 2, 3, or even 20 numbers. Writing a function with a fixed number of parameters won't cut it.

Enter the rest parameter (...) โ€” one of Javascript's most helpful function features! (Remember the rest operator, ..., from our "All About Javascript Operators" article)

Example: Sum Anything! ๐Ÿงช

function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

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

What's going on here?

  • ...numbers is not magic โ€” it's a special rest parameter (a parameter using the rest operator(...) to gather all the arguments passed).

  • It gathers all the arguments into an array called numbers.

  • Inside the function, you can treat it like any regular array (reduce, map, forEach, etc).

So calling sum(1, 2, 3, 4) becomes like doing:

sum([1, 2, 3, 4]);

(but without you needing to create the array manually).

When to Use Rest Parameters ๐Ÿ“Œ

โœ… You want a flexible function that accepts variable inputs.

โœ… You're building something like:

  • A math utility (sum, average, multiply).

  • A logger: log("info", "error", "warn").

  • Any function where the number of arguments isn't fixed.

๐Ÿง  Rest โ‰  Spread

Don't confuse rest parameters with the spread operator (...) โ€” even though they look the same, they do opposite things.

SyntaxPurpose
...restGathers items into an array
...spreadSpreads items out of an array

Example of spread:

let arr = [1, 2, 3];
console.log(...arr); // 1 2 3 (spread the array values)

Best Practices for Function Parameters ๐Ÿ› ๏ธ

To make your function APIs friendly, maintainable, and intuitive:

โœ… 1. Order Matters

Always write:

function myFunc(requiredParam, optionalParam = "default", ...rest) {
    // ... Block of code that does something
}

Why?

  • JS matches arguments left to right.

  • Putting a default before required (e.g., function(x = 1, y)) will confuse JS and you.

โœ… 2. Keep Parameters Reasonable

If your function has more than 3โ€“4 parameters, stop and ask:

๐Ÿ“ฆ Should I be grouping these into an object?

Example:

function createUser({ name, age, role = "guest" }) { ... }

Way easier to handle.

We'll explore more about objects in a later article โ€” stay tuned!

โœ… 3. Use Defaults and Rest for Friendly APIs

function greetUsers(greeting = "Hello", ...names) {
  for (let name of names) {
    console.log(`${greeting}, ${name}`);
  }
}

greetUsers("Hi", "Luna", "Marco", "SK");
// Hi, Luna
// Hi, Marco
// Hi, SK

This is flexible, forgiving, and just works โ€” the dream setup for any API!

Return Values: Sending Data Back from a Function ๐Ÿ”

So far, we've seen functions that do things โ€” like printing messages or logging stuff to the console. But what if we want a function to calculate something and give us the result?

This is where return comes in โ€” it lets a function send back data to the place it was called.

Think of it like this:

โœ‰๏ธ A function does some work, puts the answer in an envelope (return), and mails it back to the caller.

Example: Simple Addition Function ๐Ÿงช

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

let sum = add(5, 7);
console.log(sum); // 12

๐Ÿ” What's happening here?

  1. add(5, 7) is called.

  2. Inside the function, a + b evaluates to 12.

  3. The return statement sends that value back to where the function was called.

  4. sum gets assigned the returned value โ€” 12.

  5. console.log(sum) prints 12.

So in short:

๐ŸŽฏ return gives data back.

๐Ÿ› ๏ธ return vs. console.log โ€” Don't Mix Them Up!

๐Ÿ”น return:

  • Used to send data back to the caller.

  • Can be stored in a variable.

  • Makes functions reusable and composable.

๐Ÿ”น console.log:

  • Used to display output for humans.

  • Prints to the developer console โ€” but doesn't give anything back.

Let's clarify with an example:

function logSum(a, b) {
  console.log(a + b); // Only prints
}

function returnSum(a, b) {
  return a + b; // Sends value back
}

let x = logSum(3, 4); // prints 7, but x is undefined
let y = returnSum(3, 4); // y becomes 7

console.log(x); // undefined
console.log(y); // 7

๐Ÿ“Œ If your function uses console.log but no return, it will return undefined by default.

๐Ÿง  Why Use return?

Here's the big idea:

You want modular code โ€” small functions that do a job and send back results.

That way:

  • You can chain them together.

  • You can test them easily.

  • You can reuse them in different contexts.

๐Ÿ”„ Returning Early (Early Exits)

You don't have to wait until the very last line of a function to return.

function isEven(num) {
  if (num % 2 !== 0) return false;
  return true;
}

console.log(isEven(4)); // true
console.log(isEven(7)); // false

Here, we return early if the number isn't even. This avoids unnecessary checks and keeps the function clean.

๐Ÿงจ Gotcha: Functions Without return โ†’ undefined

If your function has no return, it will automatically return undefined.

function noReturn() {
  let message = "Hi there!";
}

let result = noReturn();
console.log(result); // undefined

The function ran, but since there was no return, it gave us nothing back. This is okay for helper functions but not for calculations.

๐Ÿงพ Wrapping Up: You Just Levelled Up!

Congrats, you've just taken your first big step into Javascript functions! ๐ŸŽ‰

Let's quickly recap what you now understand like a pro:

  • โœ… What a function is and why it's a superpower for your code

  • โœ… How to define and call functions โ€” including best naming practices

  • โœ… The difference between parameters and arguments

  • โœ… How to pass multiple arguments, handle missing values with default parameters, and accept an unlimited number of values using rest parameters

  • โœ… How and why to use return to send data back

  • โœ… Common beginner mistakes and how to sidestep them like a pro ninja ๐Ÿฅท

By mastering these fundamentals, you're not just writing code anymore โ€” you're designing clean, reusable, readable, and future-proof programs that are easier to debug and maintain.

You've now built the core foundation of functional thinking in Javascript. ๐Ÿ”ง Whether you're building calculators, user interfaces, games, or APIs, functions are your Swiss Army knife ๐Ÿ”ช.

You're building real momentum now ๐Ÿš€ โ€” and we're only getting started.

Next up, we'll dive deep into function expressions and how they differ from declarations, what IIFEs are and the mighty Arrow functions, exploring when and why to use each.

We'll also look at scope โ€” where variables "live" โ€” and why understanding it can save us from some of Javascript's trickiest bugs.

Until next time, keep your functions clean, your arguments clear, and your return values on point. ๐Ÿ’ก

Stay curious, stay sharp โ€” and remember: code is craft. ๐Ÿ‘จโ€๐Ÿ’ป๐Ÿ‘ฉโ€๐Ÿ’ป

0
Subscribe to my newsletter

Read articles from Sangy K directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sangy K
Sangy K

An Introvert Coder | Trying to be a Full-stack Developer | A Wannabe Content Creator