# JavaScript Functions

%[https://youtu.be/2MZHZ7A2_lA]

---

Functions contain block scope that holds a particular task (action) to be reused anywhere in a program (script) - when **called** or **invoked**.

See one of the syntaxes of a function below:

Syntax:

```
function functionName(para1, ..., paraN) {
    // statements
};

// calling, invoking, executing or running a function below
functionName(arg1, ..., argN); 
```

The syntax above contains the following:

1.) *Function head*: Contains the function keyword, `function`, the function name, `functionName`, and parameters in the parentheses, `(para1, ..., paraN)`.

Parameters are like variables that hold values.

Function head that does not require parameters for the **function body**, the parentheses can be blank.

```
function functionName() {...}
```

2.) *Function body*: The function body is whatever in the curly braces `{}`. One or more variables, statements, or expressions in the function body are locally scoped - the exception is the `var` variables.
 
3.) *Function caller*: Function callers are reusable but globally scoped. It's actually called the calling function.

In the syntax above, the function caller is `functionName(arg1, ..., argN)`. Function callers invoke, run, execute or call a function.

Syntax:
```
functionCaller = functionName(arg1, ..., argN);
functionCaller;
```

Arguments are values to a parameter.

See the example below:
```js
const currentAge = 3; // Global Variable

function getAge(birthYear, currentYear) {
    const currentAge = currentYear - birthYear; // Local variable
    console.log(currentAge);
};

const myAge = getAge(1993, 2050); // function caller in an expression
console.log(currentAge); // 3

myAge; // 57

/*
57
3
*/
```

The parameters in the parentheses are declared in the function body already. That is no need to use `let` or `const` to redeclare the variable in the function body.

In the example above, `currentAge` is a **local variable**; while `myAge` is a **global variable**. 

> Local variables are in the function body (**local scope**), while global variables are outside the function body (**global scope**).

There are four ways of creating functions:
1. Function Declaration
2. Function Constructor
3. Function Expression
  - Anonymous Function
  - Arrow Function

---
### Function declaration
To create or declare a function, it looks like syntax below:

```
function name(parameters) {
  // function body statements
}
```

See the example below:

```js
function getAge() {
  let birthYear = 1993; 
  let currentYear = 2050;
  const currentAge = currentYear - birthYear;
  console.log(currentAge);
};

const myAge = getAge(); // function caller in an expression

myAge;
```

The code snippet above is the same as shown below:
```js
function getAge(birthYear, currentYear) {
  const currentAge = currentYear - birthYear;
  console.log(currentAge);
};

const myAge = getAge(1993, 2050);

myAge;
```

For functions that contain more than three parameters, it is advisable to use **rest parameter**

> The rest parameter syntax allows a function to accept an indefinite number of arguments as an array, providing a way to represent [variadic functions](https://en.wikipedia.org/wiki/Variadic_function) in JavaScript - [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).


#### Function declaration hoisting
Declarations moved to the top of the current scope are called **Hoisting**.

See examples below:

```js
// called function before declaration
console.log( getMessage('John', 2055, 2150) ); 

function getMessage(name, birthYear, currentYear) {
  const currentAge = currentYear - birthYear;
  console.log(`${name} is ${currentAge} years old.`);
};
```

Below shows how the engine interprets the code above.

```js
function getMessage(name, birthYear, currentYear) {
  const currentAge = currentYear - birthYear;
  console.log(`${name} is ${currentAge} years old.`);
};

console.log( getMessage('John', 2055, 2150) ); 
```

---

<a href="https://www.whogohost.com/host/aff.php?aff=7390&page=hosting" target="_blank"><img src="https://www.whogohost.com/images/affiliates/unlimited-hosting-728-x-90.png" /></a>

---
### Function Constructor
A function constructor is used to create a function. 

<!-- *Avoid the function construct because it's a mistake by JavaScript creators. It creates an object which is a function* -->

The syntax below is possible because functions are *first-class objects* in JavaScript.

```js
const calcArea = new Function ("length", "width", "return length * width");

const area = calcArea(4.3, 3.1);

console.log(`The area is ${area} m²`);
```

Syntax:
```
function = new Function ([arg1, arg2, ...argN], functionBody);
```

The `new` keyword instantiates a new `Function` object. 

The example above is the same below:

```js
function calcArea(length , width) {
  return length * width;
  // console.log('Statements after the return statement get ignored!')
}

const area = calcArea(4.3, 3.1);

console.log(`The area is ${area} m²`);
```

Statements after the return statement get ignored! The `return` statement returns a value from a function.

Function constructor does not support hoisting.

Let's see another example that simply prints a result to the console.

See the example below:

```js
const greet = new Function('console.log("Good day!")');

greet(); // Good day!
```

The `new Function` is not common but it turns any string into a function &mdash; receiving a new function from a server for execution.

See below:

```js
const str = ... dynamically receive code from a server ...

const func = new Function(str);
func();
```

---
### Other features of Functions
#### Return
The `return` keyword and `console.log` object are both used in a function body to print results to the console when calling the function.

The `return` keyword helps return a value from a function call to a global or local scope.

See the example below:

```js
function calcSum(a=4, b=5) {
    const result = a + b;

    return result;
}

calcSum();
const sum = calcSum()

function showMessage() {
    console.log(`The sum is ${sum}.`); 
}

showMessage(); // The sum is 9.
```

If `console.log()` was used in place of the `return` keyword, it returns no value or `undefined` in a different function or local scope.

See the example below:

```js
function calcSum(a=4, b=5) {
    const result = a + b;

    console.log(result); // 9
}

calcSum();
const sum = calcSum()

function showMessage() {
    console.log(`The sum is ${sum}.`); 
}

showMessage(); // The sum is undefined.
```

The example above shows we can have a function in another function. It is called **Higher Order Function**. We will see it in use more later.

#### Default Parameter
Values can be assigned to parameters before been called. These types of parameters avoid mistakes of not defining a parameter (`undefined`). 

See the example below:
```js
function getName(name='Bello') {
    return(`My name is ${name}.`);
}

console.log( getName() ); // My name is Bello.
```

When a default parameter gets created, there is no need to pass an argument to a function.

The default parameter(s) can be over-ridden if the calling function contain argument(s).

```js
function getName(name='Bello') {
    return `My name is ${name}.`;
}

console.log( getName('John') ); // My name is John.
```

The old code style of creating default parameters before **ECMAScript 2015** is shown below:

```js
function getName(name) {
    if (name === undefined) {
        name = 'Bello'
    }

    return `My name is ${name}.`
}

console.log( getName() ); // My name is Bello.
```

We will treat **function expressions** in the [next article](https://techstack.hashnode.dev/javascript-function-expressions).

**Happy Coding!!!**

---

[![Buy me a Coffee](https://res.cloudinary.com/bizstak/image/upload/v1610317510/ko-fi-trans_fr3su4.png)](https://www.buymeacoffee.com/techstackmedia)

---

### TechStack | Bluehost
- Get a website with a free domain name for 1st year and a free **SSL** certificate.
- 1-click WordPress install and 24/7 support.
- Starting at $3.95/month.
-  30-Day Money-Back Guarantee.

<a href="https://www.bluehost.com/track/belloosagienoah/" target="_blank"> <img border="0" src="https://bluehost-cdn.com/media/partner/images/belloosagienoah/430x288/430x288PW.png"> </a>
