Knowledge Base/concepts/return vs console.log in JavaScript

return vs console.log in JavaScript

return vs console.log in JavaScript is not a choice between two ways to show a value. console.log prints a value for a human. return sends a value back to the code that called the function. A function can log the correct answer and still give its caller undefined, which is why this confusion breaks tests, array methods, UI rendering, and almost every "why is my variable undefined?" debugging session.

The practical rule is blunt: use return when other code needs the value. Use console.log when you want to inspect what is happening.

The short version

CodeWhat it doesWho receives the value
return valueSends value out of the function and stops that function callThe caller
console.log(value)Prints value to the consoleThe person reading the console

They can appear near the same calculation, but they do different jobs.

function double(number) {
  console.log(number * 2);
}

const result = double(4);

console.log(result); // undefined

The first log prints 8. That does not mean double(4) produced 8 as a reusable value. The function never returned anything, so the call result is undefined.

console.log is output for inspection

console.log writes to the console. That is useful while learning and debugging because it turns invisible program state into something visible.

function formatUsername(username) {
  const cleaned = username.trim().toLowerCase();

  console.log(cleaned);
}

formatUsername("  ADA  "); // logs "ada"

This proves the calculation happened. It does not make the cleaned username available to the next line of code.

const savedName = formatUsername("  ADA  ");

console.log(savedName); // undefined

The log was a side effect. It affected the outside world by printing text, but it did not become the function's result.

return sends a value to the caller

return is how a function answers the call.

function formatUsername(username) {
  const cleaned = username.trim().toLowerCase();

  return cleaned;
}

const savedName = formatUsername("  ADA  ");

console.log(savedName); // "ada"

Now the caller can store the value, compare it, pass it to another function, render it, or test it.

function makeProfileLabel(username) {
  const savedName = formatUsername(username);

  return `@${savedName}`;
}

makeProfileLabel("  ADA  "); // "@ada"

That is the whole point of return values. They let small functions compose into larger behavior.

The bug: logging instead of returning

This is the beginner bug that looks correct because the console shows the right number:

function addTax(price) {
  console.log(price * 1.2);
}

const total = addTax(50);

console.log(total); // undefined

If the task is "show the total once," logging might look fine. If the task is "calculate the total so checkout can use it," the function is broken.

Return the value:

function addTax(price) {
  return price * 1.2;
}

const total = addTax(50);

console.log(total); // 60

This matters even more in array methods. map uses the callback's return value to build the new array:

const prices = [10, 20, 30];

const discounted = prices.map((price) => {
  console.log(price * 0.8);
});

console.log(discounted); // [undefined, undefined, undefined]

Each callback logged a discounted price, but none returned one. The fixed version returns the transformed value:

const discounted = prices.map((price) => {
  return price * 0.8;
});

console.log(discounted); // [8, 16, 24]

For the larger method choice, see forEach vs map in JavaScript.

You can log and return

Sometimes you want both: inspect the value and still give it back to the caller.

function calculateDiscount(price, percent) {
  const discount = price * percent;

  console.log({ price, percent, discount });

  return discount;
}

const discount = calculateDiscount(80, 0.25);
const finalPrice = 80 - discount;

console.log(finalPrice); // 60

That is fine while debugging. The important part is knowing which line is doing which job. The log helps you inspect. The return keeps the program usable.

return stops the function

return also ends the current function call immediately.

function getAccessLabel(isLoggedIn) {
  if (!isLoggedIn) {
    return "Please sign in";
  }

  return "Welcome back";
}

Once the first return runs, the function is done. Code later in the function body does not run for that call.

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

  console.log("This never runs");
}

This is useful for early exits. It is also why logging after a return will not help you debug anything. The code is unreachable.

Functions without return return undefined

JavaScript functions always produce a call result. When there is no explicit returned value, that result is undefined.

function sayHi(name) {
  console.log(`Hi, ${name}`);
}

const message = sayHi("Mira");

console.log(message); // undefined

A bare return behaves the same way:

function stopIfEmpty(items) {
  if (items.length === 0) {
    return;
  }

  return items[0];
}

stopIfEmpty([]); // undefined

That can be a deliberate signal, but it should be deliberate. "I forgot to return" and "this case returns undefined on purpose" are very different programs wearing the same coat.

Arrow functions have one extra trap

Arrow functions can return an expression automatically:

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

But if you add braces, you need return:

const brokenDouble = (number) => {
  number * 2;
};

brokenDouble(4); // undefined

The fixed block-bodied version is explicit:

const double = (number) => {
  return number * 2;
};

The JavaScript Arrow Functions guide covers this syntax in more detail.

When to use each

Use return when:

  • Another line of code needs the value.
  • A test should verify the result.
  • A function represents a calculation or transformation.
  • A callback must provide a value to map, filter, reduce, or another higher-order function.

Use console.log when:

  • You are checking whether code runs.
  • You are inspecting an intermediate value.
  • You are comparing what you expected with what the program actually did.
  • You are temporarily debugging a branch, loop, callback, or function call.

The clean version of most code returns useful values and logs only when inspection is needed.

Key Takeaways

  • console.log prints a value for a human; it does not send that value back to the caller.
  • return sends a value out of the function and stops the current function call.
  • A function that only logs will return undefined unless it also has a return value.
  • Array callbacks often need returned values, especially with map.
  • Good debugging logs answer a question, but good functions still return the values other code needs.
Share this article:
javascriptfundamentalsfunctionsdebugging