Dive into functions in JS🧑‍💻
Tags: javascript, webdev, beginners, programming
Published: 2023-03-06 00:30:00




A function is a block of code that performs a specific task. It can accept parameters and return values. Functions in JavaScript are treated as `first-class objects`, which means they can be assigned to variables, passed as arguments, and returned from other functions.

## Types of Functions

#### 1. Function Declaration
A function declaration is a statement that defines a function with a name, parameters, and a body.
```javascript
function greet(name) {
  console.log(`Hello, ${name}!`);
}
```
#### 2. Function Expression
A function expression is a way to define a function as an expression, which can be assigned to a variable.

```javascript
const greet = function(name) {
  console.log(`Hello, ${name}!`);
};
```
#### 3. Arrow Function
An arrow function is a shorthand syntax for defining a function expression.

```javascript
const greet = (name) => {
  console.log(`Hello, ${name}!`);
};
```
#### 4. Anonymous Function
An anonymous function is a function without a name.

```javascript
const add = function(a, b) {
  return a + b;
};
```
#### 5. IIFE
An IIFE (Immediately Invoked Function Expression) is a function that is executed as soon as it is defined.

```javascript
(function() {
  console.log('IIFE executed');
})();
```

## Function Parameters and Arguments
A function parameter is a variable listed in the function definition, while an argument is the value passed to the function when it is called.

```javascript
function greet(name) { // "name" is a parameter
  console.log(`Hello, ${name}!`);
}

greet('John'); // 'John' is an argument
```

Functions can have multiple parameters and arguments.

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

console.log(add(2, 3)); // 5
```

## Function Return Values
A function can return a value using the return statement. If a function doesn't return a value, it implicitly returns undefined.

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

const result = add(2, 3);
console.log(result); // 5
```

##  Function Scope
Variables declared inside a function are only accessible within the function's scope.

```javascript
function greet() {
  const message = 'Hello, world!';
  console.log(message);
}

greet(); // 'Hello, world!'
console.log(message); // ReferenceError: message is not defined
```
## Function Hoisting
Function declarations are hoisted to the top of the scope, which means they can be called before they are defined.

```javascript
greet(); // 'Hello, world!'

function greet() {
  console.log('Hello, world!');
}
```
However, function expressions and arrow functions are not hoisted and must be defined before they are called.

```javascript
greet(); // TypeError: greet is not a function

const greet = function() {
  console.log('Hello, world!');
};
```

## Other type of functions

#### Callback Function:
A callback function is a function that is passed as an argument to another function and is called by that function. A common use case for callback functions is with asynchronous code, where the callback is executed once the asynchronous operation is complete. Here's an example:

```javascript
function getUser(id, callback) {
  setTimeout(() => {
    const user = {
      id: id,
      name: 'John Doe'
    };
    callback(user);
  }, 2000);
}

getUser(123, (user) => {
  console.log(user); // Output: { id: 123, name: 'John Doe' }
});
```

#### Higher-Order Function:
A higher-order function is a function that takes one or more functions as arguments or returns a function as its result. A common use case for higher-order functions is with array methods like map, filter, and reduce. 
```javascript
const numbers = [1, 2, 3, 4, 5];

const doubledNumbers = numbers.map((num) => {
  return num * 2;
});

console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10]
```


## Advanced

#### Closures
Closures are a powerful feature of JavaScript that allows a function to access variables from its parent scope, even after the parent function has returned. This can be used to create private variables and functions, which are not accessible from outside the function.
```javascript
function counter() {
  let count = 0;

  function increment() {
    count++;
    console.log(count);
  }

  return increment;
}

const myCounter = counter();
myCounter(); // Output: 1
myCounter(); // Output: 2
```

#### Currying
Currying is a technique in functional programming that allows a function to take multiple arguments as a series of single-argument functions. This can make your code more modular and easier to reuse.
```javascript
function add(a) {
  return function(b) {
    return a + b;
  }
}

const add2 = add(2);
console.log(add2(3)); // Output: 5
```
#### Memoization
Memoization is a technique that allows a function to cache its results based on its input arguments. This can improve the performance of a function, especially if it performs complex calculations or data retrieval.


```javascript
function fibonacci(n, memo = {}) {
  if (n in memo) return memo[n];
  if (n <= 1) return 1;
  memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
  return memo[n];
}

console.log(fibonacci(10)); // Output: 89
```

<img src="https://media.giphy.com/media/4oMoIbIQrvCjm/giphy.gif">

🎉 Congratulations, you have now learned about `functions`