Mastering Functions: The Essential Guide to JavaScript Functionality

Mastering Functions: The Essential Guide to JavaScript Functionality

In Javascript, functions are treated as first-class citizens. Functions are where we create code that can be reused. When we write our code as functions, it is cleaner and easier to test and comprehend. A function in Javascript is an object, therefore it can be used as any other value that we may return or pass around, etc.

In this post, we will look at certain Javascript functions and try to comprehend them.


How to Define a Function

Let's look at how to define a function in Javascript. The term function in Javascript can be used to define a basic function. The function can return nothing in the first case or anything in the second.

As with the third function, arguments can be supplied to the functions. As seen below, we may assign the function's output to any variable. If we assign an undefined function to a variable, it will return undefined.

// function returns nothing
function task() {
    console.log("Handeling Task.")
}

// function returns something
function addNumber() {
    return 1 + 1;
}

// function takes arguments
function add(a, b) {
    return a + b;
}

// calling functions
task();
// assigning result of the function
const result1 = addNumber();
console.log("Result 1 : " + result1);
const result2 = add(2,5);
console.log("Result 2 : " + result2);
var a = task()
console.log(a)

If we run the above function we will get the following result.

Functions Have the Ability to Return Functions

We will invoke a function by referencing its name and following it with parentheses. If the function we are calling returns another function (as it does in our instance), we must assign it to a variable or call it right away. In the future, we must ensure that we understand the behavior of the returned function and how to use it in our code. This is known as Function Currying.

// A function that returns another function
function createMultiplier(x) {
   return function(y) {
      return x * y;
   };
}

let double = createMultiplier(2); // Call the createMultiplier function

console.log(double(5)); // Output: 10

Explanation

  • The function createMultiplier accepts a single input, x, and returns a new function. This function accepts one input, y, and returns the product of x and y.

  • We call the createMultiplier function with the number 2 as an input, and the resulting function is assigned to the variable double.

  • The function that takes an input y and returns x*y where x is 2 is known as a double variable.

  • We use double(5), which returns 2*5 = 10

Because it returns a function, createMultiplier is a higher-order function in this case. The returning function is known as closure because it remembers the value of x from the scope of the outer function.


Function Scope and Local Scope

There is no difference between "local scope" and "function scope".

Up to and including ES5 there were only two scopes: global and "not global". The latter one would be called "local" or "function". Both terms mean the same thing:

var a = "this is global scope";
function foo() {
    var b = "this is local/function scope";
  if (true) {
    var c = "this is in the same local/function scope as b";
  }
  for (var i = 0; i < 4; i++) {
    var d = "this is also in the same local/function scope as b and c";
  }
}

It is a function because it is inside the function.

Since there are more than two scopes in ES6, the phrase "local" scope may be misleading. For instance, consider block scope for variables such as let or const:

const a = "this is global scope";;

function foo() {
  const b = "this is function scope";
  if (true) {
    const c = "this is in block scope";
  }
  for (let i = 0; i < 4; i++) {
    const d = "this is also in block scope but different to c";
  }
}

What is an anonymous Function?

The function expression, often known as the anonymous function, is a function that may be assigned as an expression but has no name. In the following example, the function with no name is assigned to the variable add. Later on, we may utilize this variable add just like any other function.

var add = function(x, y) {
    return x + y;
}
var result = add(1, 2);
console.log("Result : " + result);

Here is the output of the above anonymous function like any other function.

There is a distinction between anonymous and regular functions.

var result = addition(100, 30);
console.log("Result : " + result);
var anonymousResult = add(10, 30);
console.log("Anonymous Result : " + anonymousResult);
var add = function(a, b) {
    return a + b;
}
function addition(a, b) {
    return a + b;
}

Let’s take this example. We have defined two functions at the bottom and accessed both functions before they are defined. But, it throws an error in the case of an anonymous function because function hoisting doesn't work for the anonymous function.


Self-Invoking Functions

Self-invoking functions are functions that are invoked without being called. All we have to do is wrap the function in parentheses and add another at the end. As seen below, we may also supply parameters to the self-invoking function.

(function (x) {
  var a = 10;
  var b = 200;
  console.log("I am self invoking function");
  var result = a + b + x;
  console.log("Result : " + result);
})(1000);

Here is the Result. As soon as we define the function it is invoked without being called.


this keyword in functions

Understanding the keyword this is critical in Javascript. The term always relates to the context in which the function is running. In its original design, this keyword was meant to point to an instance of an object in class definitions.

const person = {
  firstName: "John",
  lastName : "Doe",
  id       : 5566,
  fullName : function() {
    return this.firstName + " " + this.lastName;
  }
};
console.log(person.fullName())
//Output
John Doe

The this keyword refers to different objects depending on how it is used:

In an object method, this refers to the object.

Alone, this refers to the global object.

In a function, this refers to the global object.

In a function, in strict mode, this is undefined.

In an event, this refers to the element that received the event.

Methods like call(), apply(), and bind() can refer this to any object.

Arrow Functions

Arrow functions are the functions' shorter syntax and do not have their own this context. When we use the keyword this within a lambda function, we are referring to the lambda function's nearest parent.

We can define these Arrow functions in the following way.

var add = (a,b) => a + b;
var printAndAdd = (a, b) => {
    console.log(`a:::${a}:::b:::${b}`);
    return a + b;
}
add(2,3);
printAndAdd(200, 300)

If we simply have one sentence, we may insert it straight below the fat arrow, as seen in the first example. If we have many statements, we must surround them with curly brackets and use a return statement to return anything.


Function as Object Methods

In Javascript, all functions are methods. It is a global object method if any function is not an object method. We may define functions on objects and invoke them as if they were methods on those objects.

const calc = {
    var1: 10,
    var2: 20,
    var3: 30,
    add: function() {
        return this.var1 + this.var2 + this.var3
    },
    sub: function() {
        return this.var3 - this.var2 - this.var1
    },
    multi: function() {
        return this.var3 * this.var2 * this.var1
    }
}

On the object scores, we defined three functions. These functions are referred to as methods. One thing that is to be noted is the term this. In the last section, we can see how this relates to the context. When we call these functions, this refers to the object scope. However, in the global scope, we have the same variables, but it uses the variables declared in the object as shown in the example below.

var1 = 100;
var2 = 500;
var3 = 1000;
const calc = {
    var1: 10,
    var2: 20,
    var3: 30,
    add: function() {
        return this.var1 + this.var2 + this.var3
    },
    sub: function() {
        return this.var3 - this.var2 - this.var1
    },
    multi: function() {
        return this.var3 * this.var2 * this.var1
    }
}
console.log(calc.add()) // Output : 60
console.log(calc.sub()) // Output : 0
console.log(calc.multi()) // Output : 6000

Function Closure

If you want to learn more about function closure, I have written a separate post. You can follow this link.


Conclusion

These function principles are critical for any javascript developer to comprehend. Understanding these concepts thoroughly improves own ability to code.

Hope you found this post knowledgeable and helpful.

Happy Coding!!