JavaScript Fundamentals – Introduction to the JavaScript function – Part 1

This time, I want to focus a little bit on a more preliminary topic. Functions in JavaScript are one of the main building blocks. Bits of code inserted into functions makes code readable, therefore, more maintainable. Imagine a JavaScript program where everything is written in the global scope and the code spans over tens of thousands of lines. Nobody would want to maintain code like that!

Separating code into smaller parts by placing them inside of a function (based on operation) allows developers to easily look up which part is responsible for certain features, making the debugging process much more pleasant.

In this post, we will be going through some of the important basics of the JavaScript function. Right now, i have other topics as higher priority. Therefore, if you want more posts dedicated to JavaScript functions or similar, related topics, please drop a comment and let me know.

More...

1. What is a function in JavaScript?

In JavaScript function may initially seem somewhat mystical. I am looking at those with little to no experience in programming. This may also apply to those coming from a traditional OOP (object-oriented programming) language such as java. So therefore, I will try to keep my explanations as simple as possible. Because this is such an important and deep topic, I intend to write more than one post on functions.

A function is a block of code, written to perform a specific task.

The specific task is very important. I don't want you to make the same mistake I did while learning. In general, functions should only perform a single specific task. Performing more than one task in a single function is often a recipe disaster. Trust me, you will thank me later.

2. Why should I use functions

2.1 Code Reuse

As seen above, functions contain a body of code that performs certain operations. By writing functions, you don't have to repeat yourself by writing the same code to perform the same operation.

2.2 Readability

Placing reusable logic inside of a function can improve the overall readability of the code. In my personal opinion, programs should read like a sentence. Developers spend more time reading and maintaining existing code than writing more code. As a result programs that read like a well-structured essay save time and money. However, just because you place logic in functions, it does not automatically make your code more readable. Lets take an example of poorly written code block.

function confusingFn() {
var args = Array.prototype.slice.call(arguments, 1);
var result;
if (args.length) {
result = 0;
args.forEach(function(v) {
if (v & 1) {
args *= v;
} else {
args += v;
}
});
}
return result;
} console.log(confusingFn(1,10,20,3));

If you ask me what is going on in the code above, I would probably have to spend at least 5 minutes explaining. Since how the function works is of no importance in this post, we will not go into it. Needless to say, the function above is difficult to understand. In the next section on best practices, we will examine why the function above is so difficult to read. From my own experience writing JavaScript, I will list what I believe to be best practices when writing functions.

3. Creating your own JavaScript function

Creating your own function can be quite daunting when you are just starting out. Below are some basic guidelines in bullet point format

  • Functions can be defined with as many arguments.
  • Overloading functions does not work in JavaScript. If redefined, functions are overwritten.
javascript-functions-basics-diagram
Diagram for describing the basic syntax for defining javascript functions. @copyright thecodingdelight.com

If somewhere down the track, i create another called functionNameHere(), the previous implementation details will be overwritten with the new definition.

4. Special features of a JavaScript function

Functions have many different special features. I will go through some of its special features. However, due to this post being an introduction, I feel that certain topics should be discussed in future posts.

4.1 In JavaScript, functions have their own scope

Variables have function scope in JavaScript, instead of block scope. Using the ES6 (ECMAScript 6) let enables developers to create block scope. Check out my post for more information on variable scopes and hoisting. In the distant future (there is so many things to post about), I may write a separate series on ES6.

4.2 In JavaScript, variables can store JavaScript function

Now, you might be saying what the?! Okay, calm down, let me explain. Without getting too technical, a function is simply just another value much like a string or a number. If requested, I will explain this in more detail. But moving on, we can do the following

var number = 5;          // Seen this multiple times. I understand it.

multiply(number, 3);    // Error. Variable has not been defined yet. It is defined in the next line.

var multiply = function(a, b) {

    return a * b;

};

multiply(number,3) // Returns 15.

4.3 Function Declarations vs Function Expressions

The first point that catches your eye is the bold-font error text. The reason why I highlighted it is to make a strong statement about the difference between functions stored in variables and our conventional function declarations. We have seen plenty of examples of JavaScript function declarations (e.g. function add(a,b) { return a + b ; }). Functions stored in variables need to be defined in previous lines before being used. The reason why we have an error in the second line is because it was called before being defined. In JavaScript, we call functions stored in variables a function expression. Remember this, because you will see this term often in your journey as a JavaScript developer. The reason why functions stored in variables are called function expressions is because Now, the next thing on your mind is probably the next question.

What is the difference between function expressions and declarations?

Now, this in it of itself is an entire post, so I am going to summarize this in a few sentences. A function expression can be passed into another function as a variable. To understand simple example (written purely for demonstration purposes) example below.

var log = function logText(text) {
console.log(text); // log text onto the console.
}; function executeFn(actionFn) {
return function(text) {
actionFn(text);
}
} var logToConsole = executeFn(log); // Generate function for logging logToConsole("This is sparta!!!!");

For beginners, the code above can be slightly difficult to understand. Lets break the code snippet down together. An anonymous function is assigned to the variable log. Anonymous function is simply a term for a function that has no name. If i wanted to, i could have given it a name. For debugging purposes, I highly recommend naming functions. I realized that I've been rambling for too long on a single topic, so I will most likely write more about function expressions vs function declarations in a separate post.

In the code above, we explore the concept of closures. Closures are the workhorses of all major JavaScript libraries and asynchronous programming. For more information on closures, please read understanding closures in JavaScript.

5. JavaScript Function Best Practice

I am sure that if all the developers in the world gathered together, we could write tonnes of books just on best practices. In the future, I will write a series on recommended best practices. Please bear in mind that the points mentioned below are not absolute. However, I have tried to list only the points that most developers tend to agree up. Tips that will help you, as a reader, become a better programmer by writing functions that are easy to follow. Therefore, in this post, I will pick out the few that I think will help you in your journey as a beginner. They are not absolute rules, but rather, my personal recommendations. Others may disagree with what I specify below (and most likely, with good reason too).

5.1 Give your functions meaningful names

The first point I would like to make in the code snippet above is that the name itself is confusing. confusingFn does not even describe the task that the function carries out. Take a look at the following line.

console.log(confusingFn(1,10,20,3));   // What the heck is this logging?

If consumers are unable to identify or get a general gist of what a function does by reading the name, chances are, that's a pretty crappy name.

5.2 Generally, functions should perform only a single specific task

To back up the statement, let us examine a very simple example.

function add(a,b) {

    var sum = a + b;

    console.log(sum);      // logs the sum to the console. To remove the side-effect, delete this line and the line above and simply type in "return a + b;".

    return sum;

}

While the code above may seem harmless, it is doing more than one thing: it is logging the result. Doing something that is far from the function's original purpose is confusing at best. Let me explain why. Without examining the code, consumers of the API cannot identify the side effect. As a result, they may spend minutes or hours pouring over their own code base to try and find the problem. With the example above, it is not much of a problem, but think of a function that does 3 or more different things behind the scenes in an application with tens of thousands of lines of code. In the long run, functions that perform multiple tasks do more harm than good. One of the few exceptions I can think of is an initialization function. This should however be well-documented.

function init() {   // For new programmers, init stands for initialization. 

     // activate scheduler

     scheduleInit();

     // get list of subscriberList();

     var subscribers = getSubscriberList();

      // activate email Sending Schedule

     activateEmailSchedule(subscribers);

     // More complex application initialization logic

}

In the initialization sequence above, doing more than one thing cannot be helped. Initialization is complex and involves many steps. However, these steps should be well-documented.

5.3 Document only when necessary

Needless to say, comments help understand complex logic. Generally, you should code in a manner that is self-explanatory, but this is often easier said than done. This is when documenting plays a crucial role in making sure that the next developer who comes across the code base can quickly figure out what is going on. This could be you in a few months time. However, this does not mean litter every single piece of code that you write with documentation. Let me make this clear: the less documentation, the better. But wait, didn't I just say that documenting plays a crucial role? Yes it does, but only when the logic is complicated. Document ONLY when it is necessary.

If possible, keep each function as simple as possible. Really good programmers are able to make programs read like an essay with very simple and clear sentences. Aim for that. When starting out, it will seem impossible. I was also in the same boat. Persevere, and eventually, you will be spitting out cleaner code as though it is second nature.

5.4 Name your Function Expressions

Well, they say that a picture is worth a thousand words. Below is a visual demonstration of the stack trace with named function declarations.

javascript-function-expression-named
The stacktrace of an named function-expression. The name appears in the stack trace, therefore, making the code easier to debug

@copyright thecodingdelight.com

In the code above, executeFn() returns a named function expression. Naming your functions is crucial, because the information can be seen on the stack trace. When debugging, developers need all the information they can get. Less is more does not apply when it comes to debugging. For debugging code, I recommend using chrome developer tools. It is built-into the google chrome browser and can be brought up by pressing F12 on windows/linux. Now, we will take an example at what happens on the stack trace if we use an anonymous function expression.

javascript-function-expression-anonymous
The stacktrace of an anonymous function-expression. Note that the function name is labelled as anonymous.

@copyright thecodingdelight.com

Hopefully it is starting to sink in. While this may not seem like such a big deal in our example, when working on large application with tens or hundreds of thousands of lines, having named functions can save you hours or possibly even days. Get into the habit of writing named function expressions. It forces you to become more intentional when designing functions. It may be hard at the beginning. However, all the little effort made will ultimately add up towards building up your skills as a developer.

5.5 Functions in JavaScript should not be more than 20 lines

While this is subject to discussion, I personally feel that if a function is longer than 20 lines, it becomes difficult to digest. Don't believe me? Take a look at any 20+ line function and let me know how long it takes for you to understand its implementation details. I know that sometimes it can be difficult to keep complex logic underneath 20 lines. If it goes over though, I am certain that the 20+ line code can be broken down into fewer simple tasks. If you don't understand what I am taking about, take a look at the init() example in a previous section. Code is written not for the machine, but for the developer to read, write and maintain. That somebody could be your junior, co-worker or even yourself in a few month/years time. Do the world a favor and write code that is easily readable and maintainable.

6. Word of advice when learning functions

Ultimately, when learning a language, you want to first get accustomed to it. One of the ways to do that is to practice using its built-in features. For example, try using an array to store variables. Learn the basic operations of an array (E.g. push(),pop(), etc.). Becoming accustomed to these features will pay dividends in the long run. Trust me, it all builds up. At first, you may not fully understand what is going on. But practice it, nevertheless by typing it out yourself. Just understanding the theory without writing a single line of code will not get you anywhere. In the future, I will write a separate blog post dedicated towards learning techniques.

But for now, practice writing good functions. Try building something with your knowledge. It is important to continue to apply newly acquired knowledge. Below are some ideas for possible projects.

  • Calendar
  • Slider
  • A simple JavaScript quiz app
  • Calculator

Another great way to learn is to do coding katas at codewars. These exercises range from super easy to extremely challenging. Therefore, it is suitable to any programmer, regardless of your skill level and years of experience.

And lastly, I hope that this post was informative and well worth your time. If this article helped build up your JavaScript knowledge, please let me know via commenting. Your comments and feedback mean a lot to me. Once again, thank you so much for taking time to read through this. Please feel free to contact me if you would like for me to post on a certain topic or answer a question. Enjoy life and have fun coding!

 

About the Author Jay

I am a programmer currently living in Seoul, South Korea. I created this blog as an outlet to express what I know / have been learning in text form for retaining knowledge and also to hopefully help the wider community. I am passionate about data structures and algorithms. The back-end and databases is where my heart is at.

follow me on: