Function of a function
Tags: javascript, functional, programming, webdev
Published: 2021-05-14 07:06:49

Good day guys, the first time i heard about function of a function was when i took an advanced algebra class and i kid you not i was on a foreigner on Jupiter the whole semester, that class was a real hell and i ended up leaving the class entirely, not that advanced algebra was too hard, but maths is not my thing and my lecturer didn't make matters any easier. That said this is not an introduction to advanced algebra rather it is your friendly introduction to functions and how they are implemented in JavaScript.

### What is a function?

A function is an isolated block of code that we can make reference to or call to achieve a particular task.  We just wrap some logic that can be routinely used to achieve a set of task into curly braces and give it a name. The idea of function is geared towards keeping our code DRY and  **_reusable_**, we will come to the meaning of **_reusable_** later. Whether you're a beginner or advanced developer you work with functions a lot, because they make our work much easier, let's see a basic function that we use all the time;

```javascript
console.log('hello world')  //  hello world
// the log function is an example of a function call
```

The log method of the console object is an example of a function, but this is a built in JavaScript function and in the example above we are actually invoking or calling the function. When we use a function we are invoking or calling the function.

### Creating a function

We can create a function in two ways;

* using the function keyword 
* Or use arrow function syntax

Let's look at each in turn

```javascript
// using the function keyword
function nameOfFunction (parameters){
    // do something with parameters
    // do other computational task
}

// creating a FUNCTION STATEMENT
function logHero(hero){
    console.log(hero)
}

// OR

// creating a FUNCTION EXPRESSION
const logHero = function(hero){
    console.log(hero)
}

// calling the function
logHero({ name: 'superman', alias: 'clark kent'})
// { name: 'superman', alias: 'clark kent'}
```

To create a function using the function keyword you type the function keyword, space and then the name of the function which is followed by parenthesis, inside that parenthesis we can define one or more parameters that our function will rely on when we call it. The next thing is to enclose all of the logic we want inside curly braces. Anytime we call the function and pass arguments to it, it runs the code inside the curly braces.

Functions can also be passed as values to variables and that variable will serve as the function name, personally i always use this method to write my functions, this type functions are called function expressions. Using the function keyword before name of the function is called function statements. If you find yourself using function expressions then you should be using arrow functions.

```javascript
// using arrow functions
const logHero = (hero) => {
    console.log(hero)
}

// since we have one argument we can omit the parenthesis
// since we are performing only one task we can omit the curly braces
const logHero = hero => console.log(hero)



logHero({ name: 'superman', alias: 'clark kent' })
// { name: 'superman', alias: 'clark kent' }
```

Arrow functions are shorter to write and they keep your code clean as we saw above, we reduced 3 lines of code to just one. if we are expecting just one parameter we can ditch the parenthesis and also if we are just doing one thing, the we can also ditch the curly braces.

### Function Scopes

A Scope simply refers to a lexical environment that stores the variables and function declared within it, every function has it's own scope. Let's get a better view of function scopes;

```javascript
// GLOBAL SCOPE

// Every function has access to this lexical environment,

const x = 1;

function logNum(){
    
    // logX SCOPE Only logX has access to this scope
    
    const y = 2;
    
    // logX has access to the scopes outside it, GLOBAL SCOPE
    
    console.log(x, y) // 
}

logNum() // 1, 2
```

A scope will generally contain other functions and variables. Thus the function on any scope has access to the variables and functions in it's own scope and those outside of it but not to scopes that belong to functions declared within it. Think of scope like, you can see what's on the same level with you or higher/outside but not lower/inside. This is good to prevent variable name collision and also to tie different values to the same variable on different scopes.

```javascript
// GLOBAL SCOPE

const x = 2

const logNum = () => {
    // logNum Scope
    
    let x = 4
    console.log(x)
}

logNum() // 4
```

## PURE AND IMPURE FUNCTIONS

Following from what we noted about scopes this leads to classify our functions into two main categories, we have;

* Pure functions
* Impure functions

### Pure Function

Pure functions are functions that only mutates values that are within it's scope, the logic inside a pure function has no effect on the lexical environment outside it because it has no business with them. One thing about pure functions, given the same input they will always return the same output, these  reasons are why they are considered pure.

```javascript
// PURE FUNCTIONS

let makeHero = (name, alias) => { name, alias } 
// makeHero has no business with anything outside it's scope

let hero = makeHero('spiderman', 'Peter Parker')

console.log(hero) // { name: 'spiderman', alias: 'Peter Parker'}

let hulk = makeHero('hulk', 'Bruce')

console.log(hulk) //{ name: 'hulk', alias: 'Bruce' }
```

### Impure Functions

These are functions that make changes to variables that are defined outside it's scope, the result of their computation depends on the other variable declared outside it's scope. It's not really advisable to use impure functions, they can cause some hard to find bugs.

```javascript
// IMPURE FUNCTIONS

// GLOBAL SCOPE

const hero = {}

const modifyHero = (name, alias) => {
    
    // modifyHero SCOPE
    
    hero.name = name
    hero.alias = alias
    
    // Accessing hero which is declared in GLOBAL SCOPE
    
    return hero
    
}

hero.universe = 'MCU'

let hulk = modifyHero('hulk', 'Bruce')

console.log(hulk)
// { name: 'hulk', alias: 'Bruce', universe: 'MCU' }
```

## Functional Programming

JavaScript is a functional language, this implies that we can build our application using functional programming techniques because in JavaScript we can;

* Pass functions as arguments to other functions
* return functions from functions

Functions that accepts functions as arguments or return other functions are called higher order functions, a good example of functions accepting other functions as arguments is found with some of the methods associated with the array class, e.g forEach, find, filter, reduce etc.

```javascript
const myArr = [2, 4, 5, 7, 8, 12, 17]

myArr.forEach(num => console.log(num%2 == 0))
// we just passed in arrow function to the forEach method

myArr.filter(function(num){ num < 6})
// we can also use functions wth the funcion keyword
```

Functional programming helps us achieve things like using callback based code where we write a function that accepts another function as an argument, it we then call the argument which is a function after we have done some task, making it wait.

### Arguments, Parameters, This??

Let's clear somethings, most people including me before in many of my previous post used arguments and parameters interchangeably however i recently discovered that they are two different things. 

A parameter is the variable that your function is depending on to do the things you are asking of it to, that is when we write the function logic we specify that it requires a parameter. 

An argument is the actual value that we call the function with, when we call the function we do so with an argument.

### This?

In JavaScript a function is an object, i don't know why on earth that makes sense. But since JavaScript is a prototype base language then i guess it actually does, well we are looking at functions today and not OOP but what does **this** means inside our functions?

#### Standard functions

A standard function will not explicitly hijack the value of this and set it equal to it's own self, rather this will refer to the the object with which the function is defined, if the function is defined on the global scope without being attached to a method to an object, then this will refer to the gloabl this. There is no lexical scoping of this.

```javascript
function Hero (name) {
    
    const _name = name
    
    function get () {
        return this._name
    }
    
    function set (name) {
        this._name = name
    }
}

// this will always refer to a prototype of Hero
```

In the above code block since we used the function keyword to declare our functions, we can be rest assured that whenever we make use of _this_ it will always refer to an instance of a hero, but since JavaScript uses prototypes, we say a prototype of Hero.

### Arrow Functions

Arrow function might be cool for short and clean code but they have an annoying habit of showing themselves. They lexically scope the value of **_this_** to be equal to themselves?? If you are doing some deep work with OOP then i would advise that you refrain from arrow functions and stick with the keyword..

That's it, your friendly introduction and reminder about functions, feel free to leave a comment below as they are welcomed and valued, you could also drop in a few cool things about functions that skipped me or better that i don't know about. Hope you find this useful.