Javascript Functions Explained to a Five-Year-Old

Javascript Functions Explained to a Five-Year-Old

Javscript Closures, Scopes and More

The thing about knowledge is that it is not in one place like you can read one mathematics textbook on geometry and expect to be god, different textbooks bring different things to the table. (Geometry is not easy)

Anyway, in this article, we are doing the impossible by providing a comprehensive guide of functions with exercises and more, I promise even if you are a five-year-old reading this, you will learn a lot just trust me, OK.

What is a Function???

You have seen functions in maths and programming, right? Well, they are the same. In anywhere, a function is something that takes in input and returns output. What is passed into the function is called an argument, e.g. Imagine a function that takes in 2 numbers and adds them or squares them or one that checks if you are going to follow me (that would be nice though), just imagine, a function could be ANYTHING.

Coming Back to Javascript?

Now, let's relate everything to Javascript, how do we declare functions? We can declare functions, in the simplest way using the function keyword, (Although that's not how the cool kids do it these days, we will get there.)

function addTwoNumbers(x, y){
        console.log(x + y)
}

Our function is very simple, it takes two numbers x and y, and prints the result. (The two numbers it takes are called arguments, bet you forgot). I know it is quite early but try to make an age calculator (basically takes in years and returns them in days)

Why are getting undefined from our function? well, you might know but we will come back to this later.

Function Scoping ()

Listen up, well uh I mean read up, A scope is like an environment. (Note env is the same as environment in this article)

let followers = 6

This is the default env, we assign a variable to followers and it is easily accessed from anywhere in our program. This env is called the global scope but functions have their env called the local scope and this local scope is local i.e. it is only accessible through our function and our function alone. It sounds simple but when we get to more complex stuff like closure make sure to remember this alright.

let followers = 10000
//One Day we will get there
function back_to_reality(){
let followers = 6
 console.log(followers)
}
back_to_reality()

What is the output of this code? 10000 or 6. Well, the answer is 10000 why? just kidding the answer is 6 because functions have their own environment rather scope, it only sees the followers it knows, the one which is defined inside of it.

Functions as Values

We defined a function as something that takes in input and returns a value right? Our function isn't returning a value which is why we that undefined in the console.

function addTwoNumbers(x, y){
        console.log(x + y)
}

Remember this function, well we are going to assign it to a variable and try to access it.

let you = 1
let followers = addTwoNumbers(you, 6)
console.log(followers)
// -> Result is undefined

The result is undefined, when your functions do not return anything you can't use it as a value. On the contrary, to make our functions return a usable value that we can store in a variable, we use the return keyword.

function addTwoNumbers(x, y){
        return x + y
}
let you = 1
let followers = addTwoNumbers(you, 6)
console.log(followers)
// -> Result is 7

The Call Stack

The Call stack is quite complicated and honestly, I do not fully understand it myself. Now, let's imagine you had a to-do list of tasks you wanted to do, and every time you finish one task you remove tasks from the list. (unless you like working ) but what if you are doing one task like buying bread and before you buy bread you need to get money from your mom, so you get money from your mom and then buy the bread right? The Call Stack is like a to-do list for functions, look at the following code.

function buybread(money){
    const get_money_From_Mom = getMoney() 
    console.log('The Bread has been brought.')
}

The Call Stack when this function is called goes like this, firstly, It calls the buybread function and realise that hey, before I can finish this function I need to call another function (which in this case is getMoney()) and then finishes with the rest of the function.

You might the wondering, why the heck am I learning this boring theory? why? well, when learning something as confusing as recursion, you will find it invaluable.

Javascript Closure

Prepare yourself this is an advanced javascript topic but we will try our best. Now, jokes apart we talked about function scoping a few minutes ago right? Now, we going to take it one step further.

The Essence of that lesson was to show that a function has a scope and the variables inside it are private right? Now what happens when the function is called every time, it means, it means that those variables are, are, (complete it for me), created every time they are invoked.

The fact that they are created every time brings an interesting question. What happens to the LOCAL variables when the function call that created them is no longer active? do the variables disappear? Nope! let's take an examples

function countFollower (name){
    let newFollower = name
        //closure function
    return {
        register(){
        console.log(`${newFollower} have followed Tech Upfront`)
    }
   }
}

In the above code, we do the following:

  1. Assign variable newFollowerto the argument name

  2. Return a function that runs for every instance when the newFollower variable is created

  3. You might be saying, which instance? I did not get it. Calm down and take an example.

let follower = countFollower('You')
let newFollower = countFollower('Your Friend')
follower.register()
newfollower.register()

The Output is:

"You have followed Tech Upfront"
"Your Friend have followed Tech Upfront"

Simply put, a closure is a function that runs on every instance when the local variables are created. Now, when we start talking about instances don't act confused.

Exercises on Closure

Now, honestly, I do not expect you to understand anything I have said easily, remember learning is a race, it is not about who starts it but who finishes it, do not give up on whatever you are learning! Answers are at the bottom of the article hopefully.


Exercise One: The Simple Counter

This is what you are to do:

  1. Write a function that accepts a number n as an argument

  2. Define a function, increment that runs on the INSTANCE the variable is created and the function should increment the the value of n

  3. That's all, start working.


Exercise Two: The Complex Counter

This is what you are to do:

  1. Write a function that accepts a number n as an argument

  2. Define 3 three functions: increment, decrement, and reset

  3. Note: they should be on the INSTANCE (couldn't stress this enough), and the variable is created.

  4. They should increase, decrease, and reset the numbers respectively.

  5. Example

  6.  const counter = createCounter(0);
     counter.increment(); // 1
     counter.increment(); // 2
     counter.decrement(); // 1
     counter.reset(); // 0
     counter.reset(); // 0
    

Exercise 3: A function that accepts two numbers and picks the lower one.

Exercise 4: A function that accepts a number and returns true only if it is an even number.


The Way Cool Kids Define Functions

  1. Arrow Notation
function addTwoNumbers(x, y){
        return x + y
}

It is quite boring, it can be defined like this:

const addTwoNumbers = (x,y) => {
    return x + y
}

Do not over-react, there is nothing there, functions can be defined like this

() => {
  'Hey , i am a no name function'
}

So we give the no-name function a name and suddenly we have

const addTwoNumbers = (x,y) => {
    return x + y
}

Recursion

This is a complex topic, I wanted to include it in the article but sorry next time, I'm too tired and I do not want to confuse you more than I have already done. Thanks for reading, I spent two days writing this, it means a lot.

Solutions to Exercises (only 1 )

let createCounter = function(n) {
    return () => { 
     n++
   }
};
/** 
 * const counter = createCounter(10)
 * counter() // 10
 * counter() // 11
 * counter() // 12
 */

Use the Concept of Number 1 to do Number 2 because they work on simple principle which is closure (that INSTANCE I talked about before). Numbers 3 and 4 are basically if checks, oops I shouldn't have said or written it.