Introduction
From its use as a front-end scripting language for web development, Javascript has evolved, and is now being deployed across several stacks and application environments, notable among which is its use in backend development in Node.JS. As a consequence, more and more developers and teams are leveraging on it to build applications of all types from the simplest to the most complex.
Mastery of JavaScript is therefore considered among the most important in the skillset of a (web) developer. As reported by Computer Weekly, a recent survey by software analysis firm - Cast - found that a greater percentage of developers (56%) believe that JavaScript (alongside Java) is among "the most important languages to master in the next five years". This is in comparison with C++ (38%), Python (35%) and SQL (30%).
Among the most powerful, yet sometimes underplayed, features of JavaScript is its use for functions. JavaScript is primarily a functional language, and functions occupy a fundamental place in JavaScript.
What is a Function
A function, in simple terms, is a (named) group of code that can be invoked. In other words, a function is a way to group together some code, give this group a name, and later invoke the code using the given name.
Why functions
The use of functions provide several benefits to developers. Some of these are highlighted below.
- Encapsulation and code reuse - Functions promote code reuse by encapsulating repetitive tasks or routines, potentially saving you more typing time. This also helps to avoid potential (typing) errors that could arise from having to type the group of code the function encapsulates whenever you need to execute the action(s) they perform.
- Better code organization - Functions help with organizing and managing code. Once you write the function and test that it works, you can save it and call it whenever you need it. Also, if you ever need to make a change to the code you only need to do it in one place, rather than looking for every instance where you typed the code.
- Concise and self-documenting code - They make our code shorter, and allows for cleaner syntax. Appropriately named functions make code more self-documenting.
How to define and use functions
Supposing you have a sequence of code statements that compute the sum of two numbers, and print the result to the browser, you could do this :
var a = 5;
var b = 7;
var sum = a + b;
document.write(sum);
Then, several lines of code later, you change either or both of the values stored in the a and b variables, and again set sum to equal the addition of a and b, and finally print the sum with document.write(sum);. Depending on how many times you have to execute the group of statements, it can become a nightmare, especially if the code in question is doing something non-trivial. This presents a good case of where functions can come in handy. Let's see how.
Defining a function
To convert our above code to a function: we follow these steps:
-collect our code sequence together:
var a = 5;
var b = 7;
var sum = a + b;
document.write(sum);
-Wrap the set of code between curly braces, creating a block of code:
{
var a = 5;
var b = 7;
var sum = a + b;
document.write(sum);
}
By enclosing our code within the opening and closing braces {}, we have effectively turned them into a single unit of execution (known as a code block), that can either be executed as one.
-Lastly, give the unit a name, preceded by the function keyword, and followed by a set of parentheses ():
function sumAndPrint()
{
var a = 5;
var b = 7;
var sum = a + b;
document.write(sum);
}
With that final step, we have successfully defined our function, ready to be summoned whenever we need to sum, and print the result of, the numbers 5 and 7.
The block of code in between the opening and closing curly brace is called the function body.
Calling (invoking) our function
So, we have finished defining our function, by encapsulating it within a block of code, and giving it a fancy name. But how do we use this function?
To use our newly defined function, we simply call it by its name, followed by the pair of parentheses (excluding the function keyword, and the function body):
sumAndPrint();
//prints 12
That is how simple it is to define and use a function in JavaScript.
Another term for calling a function is to "invoke" the function.
Improving upon our function
The function we have defined above is an improvement over always having to manually type the block of code it encloses everytime we need to perform the action of adding two numbers and output the result. Nonetheless, it suffers from a few drawbacks.
Firstly, the function , in its current form, can only sum the numbers 5 and 7, not any other pair of numbers. This means that if we need to sum any other set of numbers, we will have to write a different function for every new pair of numbers. This is not particularly desirable since it will be breaking the DRY (Don't Repeat Yourself) principle, and taking us back to the reason for writing functions in the first place: avoiding unnecessary or avoidable repetition.
Another problem our function - as it currently stands - suffers from is that it is doing too many (actually just two) things at a time:
It caluclates the sum of the given numbers.
It prints the calculated sum.
A good rule of thumb when creating functions is that a function should only do one thing; after all, functions are supposed to help us build modularity into our code. But our function, in its present state, breaks that rule.A third problem with our function is that there's no way currently for us to get hold of the resulting sum of the numbers after the function has finished executing. This is because upon exiting the function, the a, b, and sum variables go out of scope, and can no longer be accessed outside of the function. So, if we needed to do something with the computed value after the function completes execution, we couldn't.
Let's see how we can improve upon our function to take care of each of the issues we have raised.
Function parameters and return values
The first issue - being able to sum only the numbers 5 and 7, thus breaking the DRY principle - can be fixed by what are known as function parameters.
Function parameters are what we give a function to enable it carry out its task.
As an analogy, imagine sending a child on an errand, the errand could be to go help deliver a message to Mr. A. In this instance, you are not expecting the child to give anything tangible to Mr. A, just merely to convey a (verbal) message. That's the case with our function as it currently stands. You don't give it anything external to perform its task. Instead, the function contains within itself everything it needs to accomplish its job.
Now imagine sending the child on an errand to go help purchase some items from the local store. In this case, you would need to give the child some means of exchange, for example money, in order for the child to be able to get you the requested items. Otherwise, there'd be no way for them to get you the items you desire. In programming speak, we call such enablers (in the case of the child on errand, money) of actions "parameters". Parameters are passed to functions by including them between the opening and closing parentheses in the function definition. Multiple parameters are separated using commas.
function exampleFunction(param1, param2, param3, ...)
{
//function code goes here
}
Back to our sumAndPrint function from earlier on, what it requires to carry out its task of summation are two numbers - currently 5 and 7, respectively stored in the a and b variables. However, what we'd like to do is for the function to be able to sum any arbitrary pair of numbers, not just 5 and 7.
To achieve this functionality, we need to:
- Move the declaration of the a and b variables out of the function body. Pass them to the function as parameters, between the opening and closing parentheses.
- When invoking the function, pass actual arguments to it, which will get assigned to the parameters in the order in which they were passed. Here's what our code looks like after applying these changes:
function sumAndPrint(a, b)
{
var sum = a + b;
document.write(sum);
}
The a and b in the function's parameter list now act as placeholders for the actual values that we will pass in when we invoke the function. With this brief change in the function definition, our function can accept and sum any two numbers we pass to it.
To use our updated function, we call it as usual, but this time, we pass in the numbers we wish to sum as arguments:
sumAndPrint(3, 6);
//9.
Internally, the number 3 will be assigned to the a variable, and the number 6 to the b variable.
This solves the first issue, now let's move on to fixing the second issue we raised earlier.
In this update, we want to make our function do only one thing. This can be achieved by moving the code that does the printing of the calculated sum outside of the function. When we do that, however, we'd no longer be be able to print out the result of the computation carried out by our function, since as noted earlier, there's no way to access the sum variable outside of the function.
This brings us to the third issue noted above: how to make the result from the function accessible from outside of the function, so that we can work with it, for example to use it in another calculation or output it to the browser, as we are doing here.
It is also a good idea to rename our function - after moving the printing code out - so that it is clear it is no longer doing two things - summation and printing - but one (summation). A good name for the updated function will be "sum".
To get access to the result of the function, and hence fix the third issue identified above, we need to get our function to give us its resultant value.
Again, using the analogy of the child on errand, after getting the items from the local store, the child has to "return" the items bought to the sender. In the same way, after performing its calculation (or whatever task it is written to perform), a function can be instructed to return the results of its calculation to the caller. This is done by means of a "return" statement. The "return" statement is made up of the keyword return followed by the value we want the function to return to the calling code.
The return keyword basically says to our function, "when you are done executing, send this value back to your caller".
Applying these changes - moving out the code that prints to the browser, renaming our function, and adding the return statement - to our function, it should now look like this:
function sum(a, b)
{
var sum = a + b;
return sum;
}
In fact, we can eliminate the intermediate sum variable altogether, and just directly return the result of the expression a + b:
function sum(a, b)
{
return a + b;
}
We can store the result of calling this function in another variable and use it however we wish:
var result = sum(5, 6);
document.write(result);
You can see how the use of functions has made our code more succinct, cleaner, and more self-documenting, traits that are highly desirable as programmers. The function name "sum" speaks for itself wherever it is used in our code or by client code.
More on JavaScript Parameters
Default Parameters
The most recent version of the JavaScript specification (ES6), supports the concept of optional parameters when defining functions. In simple terms, optional parameters mean that our function parameters are assigned default values when the function is created, such that if the user does not pass any corresponding arguments when they call the function, the default values are used.
For example, we could define our sum function as follows:
function sum(a = 5, b = 7)
{
return return a + b;
}
This would allow the function to be invoked while passing: two, one, or no arguments at all.
sum(3, 6);
Here, 3 is assigned to the a variable, and 6 to b.
sum(3);
In this instance, 3 will be assigned to the a variable, and since we didn't supply a second argument, the default value of 7 will be assigned to the b variable, giving a result of 10.
sum();
In this call, we pass no arguments at all, so the default values of 5 and 7 are used, resulting in a value of 12.
Dealing with earlier versions of JavaScript
Versions of JavaScript prior to ES6 do not directly support the concept of default parameters; but we can achieve the same functionality by modifying our code slightly, while making use of a feature of JavaScript functions:
JavaScript allows us to call functions without passing any arguments, even if the function definition includes parameters.
function sum(a, b)
{
if(typeof a !== "number") {
a = 5;
}
if(typeof b !== "number") {
b = 7;
}
return a + b;
}
What's happening here? We are using the typeof operator to determine the data type of the arguments (or none) passed to the function when it is invoked.
For each parameter, if no corresponding argument is passed, the typeof will return the string "undefined" for that parameter. For example, if we call the function without supplying an argument or passing null for the a parameter, typeof a will return "undefined", so the test typeof a !== "number" will evaluate to true, and a will be set to the default value of 5. Else, the test will fail and we use the supplied number.
We could have tested for if typeof a === "undefined"
, but by testing against "number", we ensure that even if the user passed our function a string such as "hello", the default numeric values will be used for the variables. This way, our function is made more robust by being able to detect, and work around, unreasonable input.
Summary and concluding remarks
To recap, here are some of the highlights of what we did in this write-up.
- We started out by stating that functions are one of the most important concepts to master in JavaScript programming.
- We then looked at some of the benefits that the use of JavaScript functions offer us in terms of code organization and reuse.
- We proceeded to see how to define and use functions. Specifically, we saw that a function is made up of 4 parts:
- The function keyword
- A function name
- A comma-separated list of (optional) parameters
- The function body - between curly braces { }
- We saw that a function can return a value to its caller using the return statement.
- We learnt that a function is invoked by using its name followed by the parentheses ( ). Arguments to the function, if any, are passed inside the parentheses.
- We learnt that it is considered good practice to create functions that perform a single, specialized task.
- Finally, we learnt that it is possible to define functions with default parameter values in ES6 compliant browsers. We provided an alternate implementation for older JavaScript versions by a clever use of the
typeof
operator with conditional statements.
In conclusion, mastering JavaScript functions is an important part of becoming a seasoned JavaScript developer. This write up is but an introduction to functions in JavaScript. I encourage you to explore JavaScript functions in greater detail. Your ability to stand out as a JavaScript developer depends on it. Your future self will thank you for the effort.
Top comments (1)
easy to understand good work..