Introduction
Functions is one of the most important concepts of JavaScript that you must ensure to get a good understanding of. But, it could be a little challenging for newbies since a JS function can be defined in multiple forms. In this article, I'll be covering the various ways you can define a JavaScript function and their relevant use-cases.
What is a function?
In simple terms, a function is a set of statements defined in a certain order to perform an action. There are many ways in which a function can be defined. Let us look at each type with few examples.
A Simple Function
A simple function will contain the 'function' keyword followed by the function name and a set of angular brackets () which can accept optional parameters. The parameters passed within the angular brackets can be used inside the function body. The content within the function's curly braces {} is referenced as the function body. Let us look at a few examples below.
//FUNCTION DECLARATION - No Parameters
//Function (keyword) followed by the name of the function (sayHello)
//Followed by a set of '()' that can optionally accept parameters
//The statements within the '{}' is the function body
function sayHello() {
console.log('Hello');
}
//Function can be invoked using the Function Name
sayHello(); //Output -> Hello
//FUNCTION DECLARATION - 1 Parameter
//The '()' accepts the name parameter
//Using the backticks `` we can reference the variable 'name' using the syntax ${}
//Use of ${variable} was introduced with ES6
function greet(name) {
console.log(`Hello ${name}`);
}
//Invoking the function 'greet'
greet('Skay'); //Output -> Hello Skay
function displayFullName(firstName, lastName) {
console.log(`The Full Name is ${firstName} ${lastName}`);
}
//Invoking the function 'displayFullName'
displayFullName('John', 'Smith'); //Output -> The Full Name is John Smith
A Function that can return values
The above examples demonstrated functions that execute the set of statements within the function body. Let us look at examples of functions that can return a value or a set of values to the invoking statement.
//A simple function that accepts 'color' as a parameter
//The function checks the color and returns a String with the name of a fruit matching the color
function nameFruitByColor(color) {
if(color === 'red') {
return 'apple';
} else if (color === 'yellow') {
return 'banana';
} else if (color === 'green') {
return 'watermelon';
}
}
//Display the value on console returned by the function 'nameFruitByColor'
console.log(nameFruitByColor('red'));
//Output -> apple
The above example shows that the function returns a string. In fact, anything can be returned from a function such as a string, number, boolean, object, etc.
Up until now, we've seen some relatively simple examples of functions. Now, let's look at some complex variations of function declarations.
Anonymous Functions
A JavaScript function is referred to as an anonymous function when you omit the 'Function Name' from the declaration. But, the catch is that it must be assigned to a variable. Let us look at the code below.
//Main things to note in the function declaration
//Function Name is omitted
//The function is assigned to a variable 'fullName'
const fullName = function(firstName, lastName) {
return `The Full Name is ${firstName} ${lastName}`;
}
//If you console.log the 'fullName' variable as is then
//it returns the entire function
console.log(fullName);
//If you console.log without any parameters
//It displays 'The Full Name is undefined undefined'
console.log(fullName());
//If you console.log with parameters passed to the function
//It displays
console.log(fullName('John', 'Smith'));
The above syntax is also referred to as a function expression. You can treat 'fullName' as the function name and hence it is used to invoke the function.
Now, function expressions are handy when you need to pass them as parameters to other functions.
Let us look at the following example in detail:
Step 1:
Define two function expressions, one to add two numbers and one to subtract two numbers. The functions also return the value of addition and subtraction to the invoking statement.
//Function 'add' returns sum of two numbers
const add = function(a, b) {
return a + b;
}
//Function 'subtract' returns difference of two numbers
const subtract = function(a, b) {
return a - b;
}
Step 2:
Watch this declaration closely, the function 'calculate' has a simple function syntax, but it also accepts 'func' function as a parameter. In the return statement, when the code 'func(a, b)' runs, the function 'func' is invoked.
function calculate(func, a, b) {
return func(a, b);
}
Step 3
In the code below, we have two function expressions, calculateSum and calculateDifference.
In the first line, the 'calculate' function is called with the 'add' function and the numbers 6 and 4 are passed as parameters. The output of the function will be number 10.
In the second line, the 'calculate' function is called with the 'subtract' function and the numbers 6 and 4 are passed as parameters. The output of the function will be number 2.
//Two functions are made over here
//First call is to the 'calculate' function with the parameters 'add', 6 and 4
//The second call is to the 'add' function that is passed as a parameter
const calculateSum = calculate(add, 6, 4);
console.log(calculateSum); //10
//Two functions are made over here
//First call is to the 'calculate' function with the parameters 'subtract', 6 and 4
//The second call is to the 'subtract' function that is passed as a parameter
const calculateDifference = calculate(subtract, 6, 4);
console.log(calculateDifference); //2
Hope you were able to follow the above example. This pattern is heavily used in AJAX when you pass callback functions to handle success or failure scenarios.
Nested Functions
Nested functions are functions that contain one or more functions inside them. The inner functions can further contain functions and so on. Let us look at the code below to understand better.
//A Simple Function called myWorld that contains two inner functions
function myWorld() {
//Inner Function that displays My Hobbies
function myHobbies() {
console.log('Music & Programming');
}
//Inner Function that displays My Bank Balance
function myBankBalance() {
console.log('Not enough money to diplay balance!!!');
}
myHobbies();
}
//Invoking the outer function will invoke the inner function myHobbies() defined within it's body
//Output -> Music & Programming
myWorld();
//Will display an error - Cannot read property, since myBankBalance() is a private function
myWorld().myBankBalance();
Couple of things to note from the above code:
- The myWorld function contains 2 inner functions myHobbies and myBankBalance.
- When myWorld function is invoked, it will in turn invoke the myHobbies function defined in its body.
- The inner functions myHobbies & myBankBalance have access to all the variables & parameters of the outer function myWorld.
- However, inner functions are like private implementations. They cannot be invoked from outside the function. Hence, the statement myWorld().myBankBalance() will display an error.
The use of Inner functions is sort of a good starting point to understand a very important concept in JavaScript called 'Closures'. I'll discuss that in a separate article.
Immediately Invoked Function Expression (IIFE, pronounced 'iffy')
An IIFE is an anonymous function expression that is invoked immediately. You can define an IIFE as shown in the code below.
//Syntax-1
(function(param){
//Functional Code
}());
//Syntax-2
(function(param){
//Functional Code
})();
(function() {
console.log('Say Hello');
}());
The above function will be self-invoked and will display the statement 'Say Hello'. You can read more about IIFE over here.
Constructor Functions
One of the features of object-oriented is the use of a constructor to create objects. JavaScript supports this feature through constructor functions. A constructor function can be used to create many objects with predefined properties and methods. Let us look at the below example to understand it better.
//Constructor Function Phone that accepts three parameters make, model and color
function Phone(make, model, color) {
//All parameters passed to the function are assigned as properties to the Phone object
this.make = make;
this.model = model;
this.color = color;
//Method that will display the Phone's model clicking a selfie
this.clickSelfie = function() {
console.log(`${this.model} is clicking a selfie`);
}
//Displays the color of the phone
this.displayColor = function() {
console.log(`The color of the phone is ${this.color}`);
}
}
const iPhoneX = new Phone('Apple', 'iPhoneX', 'Red');
const onePlus7 = new Phone('One Plus', 'One Plus 7', 'Blue');
iPhoneX.clickSelfie();
onePlus7.clickSelfie();
iPhoneX.displayColor();
onePlus7.displayColor();
Couple of things to note from the above example:
- The function 'Phone' accepts 3 parameters and when a 'new' Phone object is created, it sets the parameters to the object's properties.
- To create an object using the Constructor Function, you must use the 'new' keyword.
- The 'this' keyword refers to the 'Phone' instance. So, when the statement iPhoneX = new Phone('Apple', 'iPhoneX', 'Red') is executed, the parameter 'Apple' will be set to the iPhoneX's property called 'make'. Whereas in the case of onePlus7, the make property will be One Plus. Hope that makes sense.
- Further, you can invoke all methods defined inside the function using the dot-operator. In the above example, iPhoneX.clickSelfie(); will output 'iPhoneX is clicking a selfie'. Whereas onePlus7.clickSelfie() will output 'One Plus 7 is clicking a selfie'.
- Also, it is considered best practice to name constructor functions using the Capital letter.
A Word of Caution!
Always remember to use the 'new' keyword to create objects from constructor functions. Forgetting the 'new' keyword and trying to create an object like the code shown below, will result in the object being created in the global window object which is really really bad.
const samsungGalaxy = Phone('Samsung', 'Galaxy S20', 'Gray');
By default, the keyword 'this' points to the global window object unless specified explicitly and hence when the 'new' keyword was not used, the object was being created as a part of the global window object.
There's a way to circumvent the above problem using the 'strict' mode on. Strict mode enforces coding guidelines and throws an error whenever it encounters unsafe code. You can use 'strict' mode as shown below.
'use strict'
function Phone(make, model, color) {
......
......
}
Arrow Functions
With ES6, JavaScript introduced Arrow Functions. It is a topic that needs a dedicated article and you can read more about it over here
Conclusion
I hope you enjoyed the article. I hope I have covered everything there's to know about JavaScript functions. Please leave your comments, likes and share it with other JavaScript newbies out there.
You can follow me on twitter @skaytech
Top comments (2)
This article is apt👌
You explained things in simple terms.
I'm glad you liked it. I wrote it specifically keeping beginners in mind. Do share it with others for better reach.