Functions in JavaScript
An introduction to functions in JavaScript- the different ways to define and call one.

Nearly every program that one writes over their programming journey will consist of functions. In this article we will cover the various ways in which functions can be defined and called in JavaScript. This article will serve as a base to build off of for future ones.
What is a function
Now, if you already know all about functions- feel free to skip this section and move on to the next. This section simply outlines the concept of functions to help beginners out a little.
A function is a self-contained block of code that can be called from other places, in keeping with the DRY (Don't Repeat Yourself) principle. It keeps us from having to repeat the same lines of code again and again. For example,
//without functions
let c = 1+3 + 1*3;
let d= 2+4 + 2*4;
//with functions
function mathOperation(a, b){
return a+b + a*b;
}
let c = mathOperation(1, 3);
let d = mathOperation(2, 4);
This is a rather simplistic example, but it explains how functions make our lives as developers a lot easier. Imagine a more complex function consisting of 10 statements. If we were to repeat that code 10 times without functions, we'd end up with 100 lines of code. You may think that this really isn't that big a deal as you can just copy-paste, however the real issue that functions solve is minimizing debugging time. Instead of sifting through a 100-line code to find bugs, you have to go through 10. A good developer always writes readable code that is easily understood by others and functions help with that.
Function declarations
In function declarations, functions are defined using the function keyword followed by an identifier, an argument list and the body of statements that must be executed when the function is called. Here is an example-
function grader(marks){
if (marks > 89){
return 'A';
} else if (marks > 69){
return 'B';
}
else{
return 'F';
}
}
In the above function, grader is the identifier, or the 'name' of the function. marks represents the arguments passed to the function and the remaining lines of code within the curly braces {} form the body of the function.
Function Expressions
Functions can also be defined using function expressions- wherein a function is assigned to a variable. For example-
let graderFunc = function grader(marks){
if (marks > 89){
return 'A';
} else if (marks > 69){
return 'B';
}
else{
return 'F';
}
}
This is exactly the same as a function declaration, except that the function is assigned to a variable. The graderFunc variable acts like any other variable would- it can be passed as arguments to other functions or returned from a function.
We can also use function expressions to create 'anonymous' functions. For example-
let graderFunc = function (marks){
if (marks > 89){
return 'A';
} else if (marks > 69){
return 'B';
}
else{
return 'F';
}
}
Notice that the identifier grader has been omitted in this example. In such cases the function can be referred to using the variable name- graderFunc.
One may wonder why we need function expressions when we already have function declarations. The reason is that it is generally more convenient to pass function expressions as arguments to other functions than function declarations as it makes code more readable. Another way in which the two methods differ is hoisting, which we will cover after the 'Calling Functions' section
Arrow functions
EcmaScript 6 introduced a whole host of new features- one of which was arrow functions. Arrow functions are basically a more compact syntax for defining anonymous function expressions. There are a number of ways in which they differ from function expressions, but they are not important for the purposes of this article (We will cover this in a future article. In the mean time, MDN's article covers this topic in detail)
Arrow functions skip the function keyword altogether and are defined as follows-
let multiply2 = (n) => {
return n*2;
};
The arguments to the function are provided within parentheses (), followed by a 'fat arrow' => and the function body within curly braces {}
Arrow functions' definitions can be made simpler if there is only one argument (like in our example). In such cases we can omit the parentheses for the argument-
let multiply2 = n =>{
return n*2;
}
Arrow function definition is further simplified in the case where there is only one statement in the function body. In such cases we can skip the curly braces {} and the return statement too-
let multiply2 = n => n*2;
// The above is equivalent to
let multiply2 = (n) =>{
return n*2;
}
When an arrow function has no arguments, the argument list is sometimes represented with an underscore _ instead of ().
let helloFunc = _ => console.log('Hello world');
// The above is equivalent to
let helloFunc = () => console.log('Hello world');
The Function() constructor
It generally isn't a good idea to define your functions using this method, as it comes with some security and performance drawbacks. Defining functions with the Function constructor is similar to eval(). It allows us to define functions during run-time.
let multiply = new Function("a", "b", "return a*b");
console.log( multiply(10, 2) );
//output: 20
The first n-1 arguments to the Function() constructor, out of a total n arguments- are the arguments that are to be passed to the function. The last argument passed to the Function() constructor is the body of the function being defined.
The Function() constructor can only be used to create globally scoped functions, not locally scoped ones. This simply means that the functions created as a result of the execution of the Function() constructor, will be members of the global object (Window in browsers and global in Node).
Calling functions
Merely defining a function does not execute it. In order to execute a function, it must be called. We call functions by adding parentheses after the function name as so-
function addTwo (n){
return n+2;
}
// The following statement calls the 'addTwo' function. Arguments are provided
// within the parentheses
let a = addTwo(2);
Immediately invoke function expressions (IIFE)
An IIFE or Immediately Invoked Function Expression is a function expression that is called immediately after its definition-
(function () {
console.log('Hello World!');
})();
// The above is equivalent to
!function () {
console.log('Hello World!');
}();
// These above are again equivalent to
( _ => console.log('Hello World!'))();
Now, one might wonder what is the need for IIFEs at all when we could just accomplish the same task without using functions. The reason is that IIFEs keep us from polluting the global scope (Window in browsers and global in Node). They are primarily used for initializing resources and for performing clean-up action out in the wild.
Function hoisting
We briefly touched upon function hoisting in the Function Expressions Section. The term 'Hoisting' refers to JavaScript's default behavior of moving all declarations to the top of the scope (current script or current function). We can make the idea clearer by looking into how function declarations differ from function expressions.
Function declarations are hoisted while function expressions are not. This means that we can call a function before it has been defined, if the said function is defined using a declaration. For example-
// The following is valid JavaScript code
let n = addTwo(3);
function addTwo(n){
return n+2;
}
(Note how we have assigned n to addTwo(3) before defining the addTwo function)
The same does not hold true in case of function expressions-
// The following causes an error
let n = addTwo(3);
let addTwo = function (n){
return n+2;
}
Hope you found this article useful. If you want to learn more about JS function parameters, check out the next article in this series!



