Javascript function definitions- traditional, anonymous and arrow approach 18th Nov 2019

In this blog we will see various function definitions possible in Javascript. I recommend this blog to be read on desktop (or a laptop) as i have included comparisons of the approaches using a table format

Let me jump right into it.Like you be aware there are few ways you can write functions in Javascript.Initially,I used to get confused between the syntaxes.Having said that I still used to manage it to make the code work.And then one day I spent some time to understand these syntaxes and that helped a lot. I came up wtih quick notes as well so that i remember the syntax without actually going to google everytime. I am sharing the way i understood it and hope it helps you as well in some way

I have compared the ways and put it in a table format (below) so that it becomes easier for you to compare( no need to scroll down etc)

Using Function keyword

The most traditional way to declare a function. If you have coded in Java,C# etc this syntax would come naturally to you.Lets take a scenario where we are trying to add two numbers.I have written a function called addSum

           
              function addSum(a, b) {
                              return a + b
                  }
              var z = addSum(2, 3);
              console.log(x);//prints 5 ofcourse
                
Using Function with a variable

Declare a variable and assign the function to this variable.Function can be invoked using the variable name as shown below I have written a function called subtractSum

                        const subtractSum = function (a, b) {
                        return a - b
                        }
                        var z = subtractSum(2, 3);
                        $("#resultSubtract").text(z);//will print -1
                        

Quick point to note here is that we still use the function keyword. Other point to note is that there is no name given to the function and therefore we also call it anonymous function

Using Arrow functions

These functions were introduced in ES6.Helps us to write functions in more concise way.These are also called fat arrow functions

Below function takes two nummbers and multiplies them using arrow syntax

                        var multiplySum = (a, b) => {
                        return a * b;
                            }
                        var z = multiplySum(2, 3);
                        $("#resultMultiply").text(z);//prints 6 
                    

I would dwell little more into arrow functions because they are kind of new and somewhat confusing for new comers.When I started I was not sure how to write an arrow function. If you are familiar with C#, then its similar to what's lambda expressions there.So if you a C# guy,you must be familiar with below code.

c#linq

Above is exactly what we are achieving through Arrow functions in JavaScript world.Just for the benefits of those who don't understand C#, what is happening above is that we have a addNum function which is supposed to take two Int parameters,sum them and return an Integer. The returned integer is printed on the console..Easyyy :-)

If you are unable to remember the syntax of arrow functions(ofcourse you can Google but I personally don't prefer googling for syntax everytime.Why not remember,saves time) ,followed 3 steps and it should help you get going the way it helped me.(Just print it and put it on your wall). Given a normal function expression,follow below steps to convert it into an arrow function

  • Remove the function keyword and just take the parameters with you if any
  • After the parameters, immediately put arrow which is represented as => There has to be an arrow somewhere isnt it. After all we are talking about arrow functions
  • After arrow is the body which is represented as {...}

and that's it.It should get you started. Ofcourse there are more variations to it which i have discussed below.But my suggestion is not to get overwhelmed with so many variations of arrow functions and options (to write even shorter syntaxes). I would suggest start with above 3 steps and learn other variations slowly.
I have provided a JSfiddle link to my above eg for you guys to play with Link to jsfiddle

Now lets look at the variations of arrow functions

sample

I will explain variations and approaches to write arrow function under different circumstances.Again, I will use a table format so that you can quickly compare the result set

    When function takes No Parameters

Traditional Approach
                        function display()
                            {
                                return 42;
                            }
                            console.log(display()); //prints 42
                        
Arrow Approach
                        var  display2 = ()=> 44
                        
OR
                        var  display2 = _ => 44
                        
OR
                        var  display2 = ()=> {
                        return 44
                        }
                        console.log(display2()); //prints 44
                        
Point to Note

Remember the three steps i mentioned earlier to convert traditional function into arrow function.That comes to use here

You see three variations in arrow function approach. All gives the same result. One point to remember is that if arrow function has single line like "44' here,then it returns the result of the expression by default. Therefore no need of explicit return statement. However, if you use the block syntax, you need to specify the return keyword

    When function takes Single Parameter
Traditional Approach
                         function display(x) 
                         {
                            return "hello"+ x;
                         }
                         console.log(display("manju"));//prints hellomanju 
                        
Arrow Approach
                          var display2 = (x) => "hello"+ x
                        
OR
                          var display2 = x => "hello"+ x
                           console.log(display("manju"));//prints hellomanju 
                        
Point to Note

If there is a single parameter no need to have paranthesis(highlighted) around the parameter( here for x ). Paranthesis is optional

    When function takes Multiple Parameters
Traditional Approach
                         function display(x,y) 
                         {
                            return "hello "+ x +" and "+y;
                         }
                         console.log(display("manju","s"));
                          //prints hello manju and s 
                        
Arrow Approach
                           var display2 = (x,y) => "hello " + x + " and " + y;
                           console.log(display2("manju","s"));
                           //prints hello manju and s 
                        
Point to Note

Parenthesis are mandatory since we have two parameters here i.e x and y

    When function is Returning object literals
Traditional Approach
                        function returnObjLiterals(x, y)
                        {
                            return {[x]:y}
                        }
                        var obj = returnObjLiterals("key", "value5");
                        console.log(obj.key);//prints value5
                        
Arrow Approach
                        
                         var returnObjLiteralsArrow2 = (x, y) => ({ [x]: y })           
                         var objArrow = returnObjLiteralsArrow2("key", "value4");
                         console.log(objArrow.key);//prints value4
                        
Point to Note

If you want the body to fit in one line then a parenthesis is required.Below will give an error

                     var returnObjLiteralsArrow2 = (x, y) => { [x]: y }    
                    

That's because,both block and object literal use curly brackets, therefore Javascript engine won't be able to differntiate between a block and an object.Therefore, parenthesis are important and a must have in this case

PS [x] syntax in both eg on left.
This is a ES6 feature.The square brackets allow you to use the string literals and variables as the property names.So what it means is that without [] around x ( i.e [x]), I wouldn't have been able to use "key" when printing to console.

Advantages of Arrow functions

I will keep this more practical and include as many eg as I can for clarity

this keyword-Enclosing Scope Context

First thing to remember is that arrow functions do not have their own execution context. What that means is that in case of arrow functions, both "this" and "arguments" are inherited from their parent function.Lets look at an eg below

Eg1:
                      
                              var key = "Outside";
                              let obj = {
                                key: "Inside",
                                printkey: () => {
                                    console.log("where am i declared?? answer is**** " + this.key); // no 'this' binding here
                                },
                                printkey1() {
                                    console.log("where am i declared?? answer is**** " + this.key); // 'this' binding works here
                                }
                             };
                            obj.printkey(); //where am i declared?? answer is****  Outside
                            obj.printkey1(); //where am i declared?? answer is**** Inside
                            

In the eg you see on left, we have an arrowfuncton called "printkey()" and a normal traditional function with "function" keyword called "printkey1()".
OUTPUT: printkey (arrow fn) prints "Outside" while printkey1 prints "Inside"

The reason for above is simple.In classic/traditional function expressions, the this keyword is bound to different values based on the "context" in which the function is called. Whereas arrow functions use the value of this in their lexical scope

You may be wondering difference between context and scope.Context, more or less is the object that calls the function.In our eg,printkey1() is called by obj so the context inside printkey1() will be of obj.On the other hand,scope is all the variables visible to a function based on where it is defied..yes where it is defined is important.In printkey this is bound to the global window object

Eg 2:
                      
                         const obj2 = {
                                    key: 'test object',
                                   tradFn: function () {
                                       console.log("inside tradFn this is "+this);
                                        return function innerFunction() {
                                            console.log("inside tradFn's return fn this is"+this);
                                            console.log("inside tradFn's return fn arguments are "+ arguments);
                                        };
                                    },

                                   arrowFn: function () {
                                        console.log("inside arrowFn this is "+this);
                                        return () => {
                                            console.log("inside arrowFn's return fn this is "+this);
                                            console.log("inside arrowFn's return fn arguments are "+ arguments);
                                        };
                                    }
                                };
                                const traditionaWay = obj2.tradFn('hello', 'manju');
                                const newArrowWay = obj2.arrowFn('hello', 'manju');
                                traditionaWay();
                                newArrowWay();
                            

In the eg you see on left,we see that there is an object called obj2. It has a property called key, and it has two functions called tradFn which returns a traditional function (marked in chocolate) and arrowFn which returns a arrow function(marked again in chocolate).When you run above you get below output

                              1.inside tradFn this is [object Object]
                              2.inside arrowFn this is [object Object]
                              3.inside tradFn's return fn this is [object Window]
                              4.inside tradFn's return fn arguments are [object Arguments]
                              5.inside arrowFn's return fn this is [object Object]
                              6.inside arrowFn's return fn arguments are [object Arguments]
                            

If you notice above output,3rd and 5th one are to be noted.3rd output prints [object Window] which means that if you would have done this.key there,it would have returned undefined.JavaScript loses scope of this when it is inside of a function that is contained inside of another function. When it is lost, by default, this is bound to global window object.

However,5th output where arrow function is returned, it is bound to obj2.Same is the case with arguments. Output at line 4 wont have access to arguments while output at at lin 6 will print both the arguments i.e hello and manju

If you are keen and extend or play with the above egamples, i have provided the JSFiddle link below
Eg 1 - Link to jsfiddle
Eg 2 - Link to jsfiddle

Use with map,reduce functions

Arrow functions is also useful with methods such as map and reduce, because I think it makes my code more readable. I will cover map and reduce in a separate blog

Disadvantages of Arrow functions
  • Its hardet to get hold of syntax for new comers
  • Since arrow functions are anonymous functions,which also means that there are no names associated with them,it becomes little challenging to debug,as when we get an error, we can't track the name of the function or the exact line number where it occurred.
  • Won't work in cases where self-referencing is required ,eg recursion
  • Cannot be used as a constructor.JavaScript implicitly prevents from doing that by throwing an exception.Eg below
                                    const obj3 = (text) => {
                                              this.text = text;
                                            };
                                    // Throws "TypeError: obj3 is not a constructor"
                                    const helloWorld = new obj3('Hello World!');
                                    

And that's it. Hope you undertood the ways to define Javascript Functions now.Email me at "techspacedeck@gmail.com" incase you have queries or feedback. Alternatively, you can fill the "CONTACT" form or drop a comment below

Did you like the blog or have questions, please add your comments