# JS Functions Demystified: Declarations vs. Expressions

You are writing a JavaScript code, and want to implement a functionality repeatedly in your code. To do that, you would have to copy paste the code multiple times to make it work. This process would eventually become taxing, and it would violate the **DRY** principle, Don't Repeat Yourself ! Functions are the solution to this problem.  
Functions are named container for a logic that can be written in two ways. Lets demistify the ways the functions can be declared and how it can be used.

## What is a Function?

Functions can be compared to a recipe card in a kitchen. It doesn't do anything unless someone picks it up, follows the instructions on the card, and creates the actual dish. In writing code, you are writing the recipe card by writing a function. Calling a function is the same as cooking from a recipe.Let's understand this through a simple example to greet user whenever a user enters a website:

```javascript
// Doing this manually for every user is painful
console.log("Hello, User1");
console.log("Hello, User2");
console.log("Hello, User3");
```

This will be a painful process when the number of user keeps on increasing. Hence, we use functions:

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

greet("User1");
greet("User2");
greet("User3");

// Output
// Hello User1
// Hello User2
// Hello User3
```

![](https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/56563be3-7074-45d5-a64f-5794e70153ab.png align="center")

The parameter gets filled with the argument whenever the function is called.

Functions can also give back a value using the `return` keyword which can be stored and used it elsewhere:

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

const total = add(5, 3);
console.log(total); // 8
```

When the `return` is encountered, the execution stops and send the value. If a value is returned, the line of code written after the return statement will not be executed.

![](https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/9600fd54-1eca-4326-be46-3f8c0b6835e0.png align="center")

## **Function Declaration Syntax**

The function declaration starts with a keyword `function`, followed by a function name, along with parameters enclosed in parentheses if the function returns.

```javascript
function multiply(a, b) {
  return a * b;
}

console.log(multiply(4, 6));   // 24
console.log(multiply(10, 3));  // 30
```

The function `multiply` is the block of code that can be called repeatedly and each function call is independent.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Function names in JavaScript use <strong>camelCase</strong> by convention.</div>
</div>

Another practical example can be:

```javascript
function addTax(price, taxRate) {
  const tax = price * (taxRate / 100);
  return price + tax;
}

console.log(addTax(100, 18));   // price: 100, tax: 18%
console.log(addTax(250, 8));    // price: 250, tax: 8%
Function Expression Syntax
```

## **Function Expression Syntax**

Function Expression is another way to create functions where a function is assigned to a variable. There is no function name as the variable name suffices.

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

console.log(multiply(4, 6));   // 24
console.log(multiply(10, 3));  // 30
```

The output is identical which means both fucntion works the same. The difference lies in how JavaScript handles the function.

## Declaration vs Expression

| Feature | Declaration | Expression |
| --- | --- | --- |
| **Syntax starts with** | `function name() {}` | `const name = function() {}` |
| **Can be called before it appears in file** | Yes (hoisted) | No (not hoisted) |
| **Stored in a variable** | No | Yes |
| **Can be passed as an argument to another function** | Technically yes, but uncommon | Yes, very common |
| **Can be anonymous (no name)** | No, name is required | Yes |
| **Common use case** | Utility functions, top-level logic | Callbacks, conditionally defined logic |

## **Hoisting**

When you execute a code, JavaScript doesn't run it line by line on the first read. Instead it scans the entire code on the first read to find all function declaration and variables and register them. This is called **hoisting**, where the declarations are placed at the top of the scope before the code runs. This means you can call a function declaration even if the call appears above the function definition in your file:

```javascript
// Calling the function BEFORE it is defined in the file
console.log(square(5));  // This works fine

function square(n) {
  return n * n;    // 25
}
```

Function expression on the other hand, does not get hoisted. The variable is hoisted instead, but not the function. When the JavaScript runs the code line by line, and finally encounters the function to assign to that hoisted variable, the variable remains `undefined` or throws an error if declared with `const` or `let`.

```javascript
// Calling before the expression is defined
console.log(square(5));  // ReferenceError: Cannot access 'square' before initialization

const square = function(n) {
  return n * n;
};
```

JavaScript know that `square` exist, but the function is not yet assigned to it. The variable lives in the **temporal dead zone** until the function is assigned to it in the case of `const` and `let`.

![](https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/0eec3e7f-e6fd-4518-8866-e34cea1a4033.png align="center")

## **When to Use Each One**

Both function definition works, the use case depends on the readability and intent.

**Use Function declaration when:** a named reuable utility is required that will not be reassigned which should be available across the file.

```javascript
// A reusable utility - declaration makes sense here
function formatCurrency(amount) {
  return "$" + amount.toFixed(2);
}

console.log(formatCurrency(9.5));   // $9.50
console.log(formatCurrency(100));   // $100.00
```

**Use a function expression when:** a function is passed to another function, assign different fucntions in different conditions, or treating the fucntion as data. Callbacks, event handlers, and configuration options are all common situations where expressions feel natural.

```javascript
const numbers = [3, 1, 8, 2, 5];

// Passing a function expression directly as an argument
const sorted = numbers.sort(function(a, b) {
  return a - b;
});

console.log(sorted);    // [1, 2, 3, 5, 8]
```

Another case:

```javascript
const isLoggedIn = true;

const getWelcome = isLoggedIn
  ? function() { return "Welcome back!"; }
  : function() { return "Please log in."; };

console.log(getWelcome()); // Welcome back!
```

## **Function Scope**

Function is JavaScript creates private space for variables declared with `const` or `let` inside the functions. Code outside the function will not be able to access the variable declared inside the function. This is known as **local scope**.

```javascript
function makeGreeting() {
  // local variable
  const message = "Hello from inside!";  // Hello from inside!
  console.log(message);
}

makeGreeting();
// trying to access from outside
console.log(message);  // ReferenceError: message is not defined
```

The function did not encounter an error, but the moment an attempt was made to access the variable from outside of the function, the variable does not exist in the outer space.

Although, a function can access variables that are declared outside. They are known as **global variables**. The function looks for the variable outside if it cannot find variable in the outer scope.

```javascript
const siteName = "MyShop";  // defined in outer scope

function showBanner() {
  // siteName is not declared here, so JS looks outward
  console.log("Welcome to " + siteName);
}

showBanner();  // Welcome to MyShop
```

The visual model is:

![](https://cdn.hashnode.com/uploads/covers/678b775e773554ab7117f20a/b230893f-2666-433a-9e72-4d9c9810103b.png align="center")

This scoping behaviour makes the function stay independent. Two functions can use variables with the same name inside its own scope without throwing an error.

* * *

Almost all of the JavaScript code that you will create will have functions at its core. In addition to knowing what a function is, how to create one using the two primary syntaxes, how to distinguish between a function declaration and function expression based on hoisting, and the scope, return values, default parameters, and passing functions as parameters.

To summarize the above: function declarations get hoisted while function expressions do not. Functions create their unique scope. Use return to get back a value whenever you need to return a value from a function, and since functions in JavaScript are also values, you can pass them around as if they were any other data type; this is what provides so much power and flexibility to JavaScript as a programming language.

* * *

**REFERENCES:**

*   [MDN: function declaration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)
    
*   [MDN: function expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function)
    
*   [MDN: Hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
    
*   [JavaScript.info](http://JavaScript.info)[: Function basics](https://javascript.info/function-basics)
    
*   [JavaScript.info](http://JavaScript.info)[: Function expressions](https://javascript.info/function-expressions)
