Home Blog JavaScript JavaScript Functions — Understanding The Basics

JavaScript Functions — Understanding The Basics

JavaScript has been growing in popularity in the last couple of years, ranking as one of the most widely used languages. More and more people decide to start their adventure with JavaScript each year. Although there are countless resources available, JavaScript has a steep learning curve. The amount of information and the number of new words and concepts may dishearten even the most persistent and determined developers.

JavaScript Functions — Understanding The Basics

Table of contents

This article covers the basics of JavaScript functions. Who can benefit from it? If you’ve just started with JavaScript and you want to know how to use basic functions, it’s right for you. If you have some prior programming experience, we encourage you to give it a try as well. You’ll strengthen your knowledge, refresh the core issues and perhaps you’ll learn something new, too.

In this piece, we’ll answer the following questions:

  • What is a JavaScript function?
  • How do you declare a function?
  • What are the function parameters, and what is the return statement?
  • What is an arrow function? How does it work?
  • What is a callback? How can you make use of it?
  • What is an IIFE?

What is a function?

A function is a block of code which can be executed as many times as you want in your script. Functions can perform tasks or calculate values, which may lead you to a question: “Why should I use functions if I can do all this without them?”

The answer to this is simple: good practices. Even if you’re just starting with coding, get used to them. If you’re a programmer and you repeat yourself in the code, most probably you’re doing something wrong. Functions can save you a lot of time (and lines of code) – you define a function once in your script file and then invoke it somewhere else.

You can pass data to a function using its parameters. When a function is done performing the specified actions, it can return the result (this is what the return statement is for).

These are the bare basics that every junior programmer must know. They are valid not only for JavaScript but for the majority of the popular languages. What is peculiar to JavaScript, however, is that a JavaScript function is an object. If you have no idea what this means, don’t worry – we’ll cover this soon.

You might be also interested in the article:

Top 10 React Libraries Every JavaScript Professional Should Know

Top 10 React Libraries Every JavaScript Professional Should Know

Declaring a function

In JavaScript, there are several ways to declare a function. It’s vital that you understand the differences between them and know when to use each method.

Function declaration

A function declaration is one of the most popular ways to create a function. Here you use the keyword function, followed by the name of the function. For example:

function doSomething(parameters) { statements };

One of the most important issues with the function declaration is hoisting. What does it mean? When the code is parsed in a browser, all function declarations (and variable declarations) are hoisted up to the top of the current scope, and they become global. The result is that, unlike in other programming languages, a function or a variable can be invoked before its declaration. It comes as a surprise for new JavaScript developers who have previous programming experience in other languages. Thanks to hoisting, the following code will work:

doSomething(); function doSomething() { console.log(‘Hello’); };

As mentioned before, the function declaration (together with arrow functions) is the most common way of creating functions in JavaScript.

Function expression

Another way to declare JavaScript functions are function expressions, where you assign a function to a variable. Here’s a sample function expression for an anonymous function:

let doSomething = function(parameters) { statements };

The difference between function expressions and function declarations is subtle, so you need to be careful to avoid serious issues. Function expressions are not hoisted, so the following code will not work:

doSomething(); // doSomething is not a function !!! var doSomething = function() { console.log(‘Hello’); };

Constructor

Constructors are rarely used to declare JavaScript functions, and they’re not considered a good practice, so we’ll only mention them briefly. Here’s a sample function created with a constructor:

var doSomething = new Function(‘parameter’, ‘console.log(parameter)’);

As the code above suggests, we pass the names of the parameters as arguments to the constructor. The last argument is used as the function body code.

Arrow function

You can’t discuss JavaScript functions without mentioning arrow functions. It’s a new function syntax introduced with ECMAScript 6, the most recent standard for writing JavaScript. Surveys show that arrow functions are the most popular ES6 feature. They’re very interesting and can save developers’ time, so we’ll discuss them in more detail a bit later. For now, let’s take a look at a sample arrow function:

const doSomething = () => { console.log(‘Hello’); };

You can immediately notice that arrow functions are very different from the examples mentioned earlier, and the differences are deeper than syntax. If you want to know what you can accomplish with arrow functions, keep reading – we’ll get there shortly.

Passing and retrieving the data

You can create a JavaScript function already, but there’s more to it. Sometimes you’ll need to pass some data to a function or get its result.

Function parameters

Parameters are used to pass the necessary data to a function. They are basically variables which we can call inside the function body and assign values to them when we invoke the function. This is a simple function with two parameters:

function printParameters(param1, param2) { let printObj = { firstParameter : param1, secondParameter : param2 }; console.log( printObj ); };

And this is its invocation:

const first = “Hi”; const second = “Hello”; printParameters(first, second);

In this particular case, when there is no value assigned to one of the arguments, it will be replaced by undefined. However, you can add default values to the parameters when you create a function:

function printParameters(param1, param2 = “Hello”) { let printObj = { firstParameter : param1, secondParameter : param2 }; console.log( printObj ); };

If you invoke this function with only one argument, the result will be the same as above:

const first = “Hi”; printParameters(first);

To wrap up the topic of function parameters, we’ll mention the feature called the rest parameter. It allows you to pass an indefinite number of arguments as an array, so you can create the following function:

function printParameters(param1, param2, ...other) { console.log(param1); console.log(param2); console.log(other); };

You can invoke it like this, for example:

printParameters(“First”, “Second”, “Third”, “Fourth”);

As you can easily guess, the function will return the words “First” and “Second.” The result of the third console.log is interesting, though. It will display an array: [“Third”, “Fourth”].

With the rest parameter, you can bundle the arguments passed to a function into an array. Consequently, you don’t have to know upfront how many arguments your function will take. Each function can have only one rest parameter, and it must be its last parameter.

The return statement

As mentioned before, you can retrieve data from a function with the return statement. For example, this is how you use it in a simple math function:

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

And this is how you invoke it:

const a = 1; const b = 2; let result = add(a, b);

Keep in mind that when the return statement is called, a function immediately stops. It’s useful because the return statement doesn’t have to be the last code line within a function body. Let’s consider this example:

function returnNumber(no) { let result; if(no === 1) { result = ‘One’; } else if (no === 2) { result = ‘Two’; } else { result = ‘Another number’; } return result; };

It’s rather long, but we can make it more concise and receive the same result:

function returnNumber(no) { if(no === 1) return ‘One’; if(no === 2) return ‘Two’; return ‘Another number’; };

Depending on the value of the argument, the appropriate instruction will be executed.

Arrow function

You know already how to create and use functions, so we can move on to some more advanced topics. We have mentioned previously that arrow functions are the most popular feature of ES6. Developers love them not only for their concise syntax but primarily for their benefits. First things first, though: let’s start from the syntax.

Syntax

Do you remember the simple math function we discussed above? Here’s how to write it with an arrow function:

let add = (a, b) => a + b;

Arrow functions allow you to omit the function keyword, and in simple functions, you can also drop the return statement. However, if you want your function to perform more complicated operations, you have to put its body in parentheses. If a function has only one argument, you can omit the parentheses.

let printParam = param => { console.log(param) };

This syntax may look startling at first. However, you can get used to it fast, especially if you use callbacks (read on to learn more).

What happens to this, or: why do arrow functions rock?

Their clean syntax is essential, but it’s not the only reason behind the popularity of arrow functions. Their top benefit is that the context of this doesn’t change.

Before arrow functions emerged, each function had its own context for this. To illustrate it, let’s analyze a simple example:

function Flash() { console.log(this); // Flash setInterval(function () { console.log(this); // window }, 500); } var hero = new Flash();

this is one of the most confusing parts of JavaScript – its value depends on the way the function was created and how it was invoked. When you use the new operator, you create a new object, whose constructor is the Flash() function. Consequently, the first this points to the newly created object. The second function was created with the function declaration, and it’s not a constructor. For this function, the default context of this is set to the global window object. As you can see, the results of both console.logs will be different. How to fix this?

In the older versions of ECMAScript you could assign this to a variable to use it within an object:

function Flash() { var self = this; self.speed = 0; setInterval(function speedUp() { self.speed++; }, 500); } var hero = new Flash();

Alternatively, you could use bind():

function Flash() { this.speed = 0; setInterval(function speedUp() { this.speed++; }.bind(this), 500); } var hero = new Flash();

Luckily, in ES6, this problem has been solved. As mentioned before, arrow functions don’t change the context of this. It means that you don’t have to assign it to a variable, because its value depends on the current scope of the function. Therefore, this doesn’t point to the global window object. Our sample function, therefore, will look like this:

function Flash() { this.speed = 0; setInterval(() => { this.speed++; }, 500); } var hero = new Flash();

This solution is far more useful, especially in object-oriented programming.

Callback

As we mentioned in the introduction, an essential aspect of JavaScript is that each function is an object. This seemingly innocuous fact has a whole lot of consequences, and we can use to create interesting solutions.

You already know that you can use function parameters to pass some data to a function. If a function is an object in JavaScript, then it can be passed as an argument, just like a string or a number. Here’s a simple example:

function firstFunction(callback) { console.log(“Second function”); callback(); } function secondFunction() { console.log(“Second function”); } firstFunction(secondFunction);

The function which is passed to another function as a parameter is called a callback.

Of course, this simple example doesn’t demonstrate the full power of callbacks. If all this is new to you, you may be asking yourself, “How can I use it? How is it different from calling multiple functions one after another?”

A common problem faced by JavaScript developers is performing certain operations after a website or an application has fully loaded. It’s a perfect situation to watch callbacks in action:

window.addEventListener(‘load’, () => { statements console.log(“Loaded !”); }

As you can see in the example below, we create an event listener together with a callback. Thanks to this, the operation will be performed when the page has loaded.

And do you remember one of the previous examples where we used a callback?

setInterval(() => { this.speed++; }, 500);

When discussing arrow functions we used the setInterval function, where we named the actions to be performed after a specified time. And now you know that in reality, we passed a function to be executed!

Callbacks are extremely useful in JavaScript. They come in handy in asynchronous events, such as API calls or listening to user actions.

Immediately-Invoked Function Expression

The last thing we’ll cover when discussing functions is IIFE (Immediately-Invoked Function Expression). As the very name suggests, it’s a function which is executed as soon as is defined. Just wrap your function in parentheses and add another set just before the semicolon:

(function() { statements })();

Thanks to the parentheses, the rest of the code can’t access the variables inside the function body. Also, you don’t have to worry that the variable names from outside an IIFE will conflict with those inside it.

Conclusion

Nowadays there are numerous courses, bootcamps, online tutorials, etc. which promise to teach you the popular technologies in no time. Often you can meet developers specializing in one framework or library, e.g., React, Angular or Vue. Before you dive in the frameworks and libraries, though, it’s best to master the JavaScript basics. If you understand its core mechanics, you can tackle more complicated problems in your programming career. Further down the road, you have to be more and more creative, because not every issue is covered in tutorials. Moreover, when you have a solid background in JavaScript, you can quickly learn any framework and library.

Some issues mentioned in this article seem trivial, but in reality, they can be a pain even to seasoned developers. Of course, we can’t cover here all aspects of JavaScript functions – one article is not enough to describe every possible option! Moreover, new solutions and ideas keep emerging, as JavaScript is still actively developed.

If you want to know more about JavaScript (and other languages too!), don’t hesitate to browse the Boldare blog for knowledge and inspiration.