Are You Familiar with Javascript Functions…Really?

Swarnendu De March 31, 2016

In a programming language a function is a procedure or routine, better to say a piece of code which may take some inputs and process them to return a result.

Javascript started its journey from 1995 and day by day it improved and became the language of the web. From 2015 ECMAScript (a.k.a Javascript) promised to release new versions in every 1 or 2 years.

Like all other programming languages Javascript also provide us functions.

In Javascript, each function is an instance of Function class and each function has a different scope. It’s very important to understand the context and scope of every function. However, we can change the scope of a function in different ways to maintain the anonymity.

10 years before we could have used two representations of JS function but since 2015, Arrow Function representation has been introduced which help to shorten the JS codes.

In this blog we will discuss the various types of function representations in ES6 and some important methods of Function, which can help us to manipulate the scope.

Function declaration

In Javascript (upto ES5) there are two ways to declare a function. But there are some differences between this two declaration. If we declare a function in this way then we can call it before declaration.

  1. function getName() {}
  2. var getName = function() {}

The below code snippet is an example of first type of declaration

//Example
var firstName = "Subhajit",
    lastName = "Ghosh";
getName();

function getName() {
    //Here this is the global context
    return (this.firstName + " " + this.lastName);
};

Advantage of this function declaration is we can call the function before declaration.

In general, there are two steps to execute the JS code in a browser. First, the browser converts the code into a optimized code and then execute it by the interpreter.

So if we declare a function like var getName = function() {} before execution “getName” is just a variable. But in the previous function declaration the browser knows that “getName” is a function.  So it’ll not return an error if execute the function before declaration.

//Example
getName(); //Return an error 'undefined is not a function'
var getName = function() {
    return (this.firstName + " " + this.lastName);
};

Class/Constructor Function Declaration

This is a simple class better to say it is a constructor function representation of Javascript. It’s a good practice to always set default values for arguments of any type of function.  If you didn’t pass any value to the function then it’ll not return any error and will execute everything using the default values.

var Person = function(firstName, lastName) {
    this.firstName = firstName || "Puja";
    this.lastName = lastName || "Deora";
    this.getName = function() {
        return (this.firstName + " " + this.lastName);
    }
}

Use of Call and Apply

“call” and “apply” are two very important methods of Javascript Function. The behaviour of both the functions are almost same.”Call” takes the arguments of the functions one by one i.e. test.call (this, arg1, arg2…). On the other hand “apply” takes the arguments as an array i.e. test.apply (this, [arg1, arg2…]).

Using call and apply we can bind any scope to a function. In this example the scope of { firstName: “Santanu”, lastName: “Nandi” } this object binded with the getName function.

getName.call({ firstName: "Santanu", lastName: "Nandi" }); // Santanu Nandi
//Another example of apply 
getName.apply({ firstName: "Sourav", lastName: "Mondal" }, []); //Sourav Mondal

Use of Bind

“bind” is one of my favourite method of Function in javascript, which helped me a lot to get rid of closures in some specific cases such as using parent scope in the callback function scope.

Let me explain  it with a simple example. In this the Person object has a separate scope but on using bind method it will refer to its parent scope for this example it is the window scope.

var firstName = "Kittu",
    lastName = "Ghosh";
var Person = {
    firstName: "Puja",
    lastName: "Deora",
    getName: function() {
        return (this.firstName + " " + this.lastName);
    }.bind(this) // Here "this" refers to window scope,
    getNameWithoutBind: function() {
        return (this.firstName + " " + this.lastName);
    }
};

Person.getName() //"Kittu Ghosh"
Person.getNameWithoutBind() //"Puja Deora"

Here I, binded the window scope with the getName function. So it will always return the firstName and lastName which is declared in the window scope.

Person.getName.apply({ firstName: "ABC", lastName: "CDF" }); //"Kittu Ghosh"
Person.getNameWithoutBind.apply({ firstName: "ABC", lastName: "CDF" }); //"ABC CDF"

If you bind the scope you cannot change the scope later. Look at the first example; there I tried to apply another object scope in getName function. After that also it returned me the firstName and lastName of window scope because it’s already binded with the window scope. But when I’m not using bind method as in getNameWithoutBind function it is working perfectly fine.

A brief introduction about ECMAScript 2015 (ES6)

On 1995 javascript was born as Livescript. After that 1997, ECMA standard established.On 1999 ES3 came. Finally on 2009 Douglas Crockford came up with the idea of OOP in javascript(ES5), what most of us use now. On 2015 ES6/ECMAScript2015 comes out with many syntactic sugar.

blog post7

The new features of ES6 are:

  1. Arrow function representation.
  2. Class keyword, inheritance
  3. Block scope, let and const keyword.
  4. Destructuring assignments
  5. Promises and template literals etc.

In this blog we mainly focused on Arrow function representation and will discuss its advantage and disadvantage.

Arrow function representation in ES6

There is an another way to declare a function in ES6 which is known as Arrow function. Mainly this is a syntactic sugar on anonymous function declaration. Here is an example of arrow function.

let firstName = "Subhajit";
let lastName = "Ghosh";
let getName = () => (firstName + " " + lastName)

Advantages of arrow representation is it will reduce boring syntax of javascript functions. The flexibility of this type of representation is if the function has only one line return statement then we don’t need any {}.

Ex: let getName=() => (firstName +” “+lastName);

There are lot of disadvantage of arrow representation of function.If you declare a constructor function using arrow representation then it will bind the scope where it is declared.

// Never do this
let Person = () => {
    this.firstName = "Subhajit";
    this.lastName = "Ghosh";
    this.getName = function() {
        return (this.firstName + " " + this.lastName);
    }
}
new Person().getName();

The above code snippet will return undefined undefined(For es2015-loose) as output because Person function binds the scope with window.

Note: for es2015-strict mode it will give you an error.

Good practice

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName || "Puja";
        this.lastName = lastName || "Deora";
    }

    getName() {
        return (this.firstName + " " + this.lastName);
    }
}
new Person().getName();

These are some more examples of playing with the scope of the functions.

Example 1

let obj = {
    firstName: "Subhajit",
    lastName: "Ghosh",
    obj2: {
        firstName: "Puja",
        lastName: "Deora",
        getName() {
            console.log(this.firstName + " " + this.lastName)
        }
    }
}
obj.obj2.getName() // Puja Deora

Example 2

let obj = {
    firstName: "Subhajit",
    lastName: "Ghosh",
    obj2: {
        firstName: "Puja",
        lastName: "Deora",
        getName: () => {
            console.log(this.firstName + " " + this.lastName)
        }
    }
}
obj.obj2.getName(); //undefined undefined (For es2015-loose)

In this example I have represented the getName() as an arrow function so the scope of getName() is representing the window scope, but this is a bad practice and it will throw an error in es2015-strict mode.

Example 3

var obj = {
    firstName: "Subhajit",
    lastName: "Ghosh",
    obj2: {
        firstName: "Puja",
        lastName: "Deora",
        getName: function() {
            console.log(this.firstName + " " + this.lastName)
        }.bind({ firstName: "Santanu", lastName: "Nandi" })
    }
}
obj.obj2.getName() // Santanu Nandi

So, function scoping is a very important thing in Javascript and if you are not aware of this you can find difficulties while writing callback functions or overriding a library functions.
In this blog I just explained one feature of ES6 but many more to come. For more updates about ES6  follow Innofied blogs. And if you have any queries feel free to ask me out.