Short and Long Syntax

Implicit and Explicit Return Statements

Todd Motto by Todd Motto Google Developer Expert Icon Google Developer Expert
JavaScript Icon

Learn JavaScript the right way

Premium JavaScript courses to skyrocket your skills to the top.

5x Courses: Basics, Masterclass, HTML5 APIs, DOM, Testing with Jest.

For ultimate reuse and encapsulation, let’s explore getting data back out of functions.

Through learning how to return values from functions, we lead to more powerful use cases.

Whilst learning about implicit and explicit return, I’ll also introduce to you the idea of a “factory function”, a software design pattern.

Let’s first take a function that creates a new item:

function makeDrink(name, price) {
  const drink = {
    name,
    price
  };
  // do something with `drink`
}

makeDrink('Lemonade', 299);

Our new drink object is ready to go, what next?

It might be tempting to add further logic inside the function, but this would start to introduce complexity and more behavior.

I believe a function should perform one job, and do it well. Even if it’s one line of code.

So, we turn to this idea of “encapsulation” and instead return the item:

function makeDrink(name, price) {
  return {
    name,
    price
  };
}

const drink = makeDrink('Lemonade', 299);
// { name: 'Lemonade', price: 299 }
console.log(drink);

Our function is small, focused and testable. It’s easy to think about when looking at the code too.

With this out the way, let’s get to the next step of the article - “explicit” and “implicit” return statements.

If you see the return keyword, you’ve explicitly returned from your function.

So what about “implicit”? All functions will return on their own, even if you don’t write it. It’s how they jump out of the current execution context and move onto the next step of your code.

If we don’t return anything, there’s no need to use return, unless we want to exit the function early.

Here’s a different example that talks to an external variable cart, does not return, therefore it implicitly returns:

const cart = [];

function addToCart(drink) {
  cart.push(drink);
}

addToCart('Lemonade');

Once the JavaScript compiler has reached the end of the function, the implicit return is made.

Essentially, that makes these example equivalent:

function addToCart(drink) {
  cart.push(drink);
  return; // explicit return
}

function addToCart(drink) {
  cart.push(drink);
  // implicit return
}

That’s not all, we’ve not talked about ES2015 (ES6) arrow functions.

Arrow functions are a more recent addition to JavaScript and are sometimes referred to as the “fat arrow syntax”.

It’s common to use arrow functions with function expressions, even as a replacement for function declarations, so let’s refactor our first example:

const makeDrink = (name, price) => {
  return {
    name,
    price
  };
};

const drink = makeDrink('Lemonade', 299);
// { name: 'Lemonade', price: 299 }
console.log(drink);

Arrow functions are unique because they feature “long” and “short” versions.

The long version allows us to use both explicit and implicit returns, and the short version will implicit return always - but with your data:

// longhand syntax
const getDiscount = () => {
  return 0.5;
};

// shorthand syntax
const getDiscount = () => 0.5;

This makes it an effective one-line function that is clear, concise and readable.

These functions are commonly seen in functional programming, and often referred to as “lambda functions”.

I switched to this example to demonstrate returning data that was not an object. Why? Because this trips people up.

Looking back at our function, an object {} also shares the same braces as the function’s opening and closing:

const makeDrink = (name, price) => {
  return {
    name,
    price
  };
};

It’s common to attempt something like this, even though at first glance it almost looks like we’re implicitly returning an object:

// ❌ Throws an Error
const makeDrink = (name, price) => {
  name,
  price
};

There’s a little trick involved that does in fact allow us to do this, but we need to wrap the object braces {} inside parenthesis:

// ✅ Works nicely!
const makeDrink = (name, price) => ({
  name,
  price
});

This tells the JavaScript compiler to treat it as an expression, and is completely valid code.

An expression is then returned and not mistaken for opening and closing function braces.

Dynamic Arguments

« Rest Parameters and Arguments

Functions into Functions

Functions as Callbacks »