Functions in JavaScript
In this tutorial, we will explore the benefits of functions in terms of code re-use and in terms of “modularizing” our code to make it more “readable”.
Setup
If you’ve completed the prior Sandbox tutorial, you can jump to the re-use portion of this tutorial to continue evolving that project.
If you want to start a new project from scratch, grab the Sandbox code and then replace the content of the main.js
file with the code below.
Expand to view main.js
console.log('main.js has been loaded');const sandbox = document.querySelector('output#sandbox');
// TODO: Use the space below for playing with JavaScript.sandbox.innerText = 'My sandbox is ready to play in.';sandbox.innerHTML += '<br>A) There are many assignment operators';
// ... remember to keep the previous codelet leftSide = 3;let topSide = 4;let area;area = leftSide * topSide;
sandbox.innerHTML += '<br>';sandbox.innerHTML += `B) The area of my rectangle is ${area}`;
let unitCost = 12.95;let gstRate = 0.05;let currency = '(CAD)';let subTotal = unitCost * 10;let total = subTotal + subTotal * gstRate;// Output the result on another "line"sandbox.innerHTML += '<br>C) ';sandbox.innerHTML += `The subtotal is $ ${subTotal.toFixed(2)}. `;sandbox.innerHTML += `The total is $ ${total.toFixed(2)}.`;
// Can JavaScript do math with strings and numbers?let numberFive = 5;let stringFive = '5';let answer;
answer = numberFive + stringFive;sandbox.innerHTML += '<br>D) ';sandbox.innerHTML += `5 + '5' produces ${answer}`;
answer = numberFive * stringFive;sandbox.innerHTML += '<br>E) ';sandbox.innerHTML += `5 * '5' produces ${answer}`;
answer = numberFive + parseInt(stringFive);sandbox.innerHTML += '<br>F) ';sandbox.innerHTML += `5 + parseInt('5') produces ${answer}`;
sandbox.innerHTML += `<br>G) numberFive is a ${typeof numberFive}`;sandbox.innerHTML += `<br>H) stringFive is a ${typeof stringFive}`;
const pi = 3.14159; // pi's value is now fixed - it can't changelet radius = 10;
sandbox.innerHTML += `<br>I) A circle with radius of ${radius} `;sandbox.innerHTML += `has an area of ${pi * radius * radius} `;sandbox.innerHTML += `and a circumference of ${2 * pi * radius}.`;
Code Re-Use
One of the aspects of the current main.js
to note is that we appear to be repeating a lot of code. Specifically, when we want to display content on the web page, we’re always doing something like this.
sandbox.innerHTML += '<br>';sandbox.innerHTML += someOtherText;
Granted, the details of the someOtherText
content varies in our script, but the essense of the idea remains: We want to a) append to the existing content, and b) ensure that each block of text appears on a separate “line” on the screen.
Author TODO: Add link on Functions to the grammar
Functions are an excellent tool for creating re-usable blocks of code. If you have two or more instructions that you want to perform repeatedly, you can simply put them in a well-named function and then call it whenever you need to perform those tasks.
There are two aspects to functions:
- Declaring - The function’s behaviour has to be declared. This is just a fancy way of saying we have to create the function.
- Calling - This is where we use the function by invoking it. In other words, we tell the computer, “Hey, take this information and go to this function to run the code in that function.”
By creating and using functions for multiple instructions, we are practicing the DRY (Don’t Repeat Yourself) principle in software development.
Append Line
Let’s improve our code by making the following changes to main.js
.
-
At the top of the file, replace the line that declares the
sandbox
variable with the following code.Function Declaration const sandbox = document.querySelector('output#sandbox');const appendLine = function(someText) {const sandbox = document.querySelector('output#sandbox');sandbox.innerHTML += '<br>';sandbox.innerHTML += someText;} -
We’ll still want to “reset” the contents of the
<output>
element, so we’ll change the first message on the page.Reset the Display // TODO: Use the space below for playing with JavaScript.sandbox.innerText = 'My sandbox is ready to play in.';document.querySelector('output#sandbox').innerText = 'My sandbox is ready to play in.'; -
Now we’ll do our first call to our
appendLine
function. Change the sampleA)
output as follows.sandbox.innerHTML += '<br>A) There are many assignment operators';appendLine('A) There are many assignment operators');Notice two things about this change. We’re writing less code (hooray!) and we don’t need to be explicit on the line break.
-
Update the display of sample
B)
.sandbox.innerHTML += '<br>';sandbox.innerHTML += `B) The area of my rectangle is ${area}`;appendLine(`B) The area of my rectangle is ${area}`); -
Our next sample display (
C
) outputs the subtotal and total values. I had us write those on separate lines just because I wanted to keep the lines short. I still want the lines short, so I’ll throw in a variable for the message I want to display.sandbox.innerHTML += '<br>C) ';sandbox.innerHTML += `The subtotal is $ ${subTotal.toFixed(2)}. `;sandbox.innerHTML += `The total is $ ${total.toFixed(2)}.`;let message;message = `C) The subtotal is $ ${subTotal.toFixed(2)}. `;message += `The total is $ ${total.toFixed(2)}.`;appendLine(message);Granted, it’s an extra line of code, but what we have done is slightly improve the readability of our code.
-
Let’s jump through a bunch of other changes where we played with strings and numbers.
// Can JavaScript do math with strings and numbers?let numberFive = 5;let stringFive = '5';let answer;answer = numberFive + stringFive;sandbox.innerHTML += '<br>D) ';sandbox.innerHTML += `5 + '5' produces ${answer}`;appendLine(`D) 5 + '5' produces ${answer}`);answer = numberFive * stringFive;sandbox.innerHTML += '<br>E) ';sandbox.innerHTML += `5 * '5' produces ${answer}`;appendLine(`E) 5 * '5' produces ${answer}`);answer = numberFive + parseInt(stringFive);- sandbox.innerHTML += '<br>F) ';- sandbox.innerHTML += `5 + parseInt('5') produces ${answer}`;appendLine(`F) 5 + parseInt('5') produces ${answer}`);sandbox.innerHTML += `<br>G) numberFive is a ${typeof numberFive}`;sandbox.innerHTML += `<br>H) stringFive is a ${typeof stringFive}`;appendLine(`G) numberFive is a ${typeof numberFive}`);appendLine(`H) stringFive is a ${typeof stringFive}`); -
We’ll finish off with improvements to our circle calculation output.
sandbox.innerHTML += `<br>I) A circle with radius of ${radius} `;sandbox.innerHTML += `has an area of ${pi * radius * radius} `;sandbox.innerHTML += `and a circumference of ${2 * pi * radius}.`;message = `I) A circle with radius of ${radius} `;message += `has an area of ${pi * radius * radius} `;message += `and a circumference of ${2 * pi * radius}.`;appendLine(message);
We’ve built our first re-usable block of code, and we’ve also encountered an important JavaScript keyword: function
.
The final result of all these changes does not alter what our code does; it still displays the same information. But our efforts in refactoring make a huge improvement in how readable our code is. We’ll discover another benefit in the next part of this tutorial.
Auto-Numbering
Wouldn’t it be nice if our code could just auto-increment the step indicators (A
, B
, etc.) each time we called appendLine()
? We can do that by introducing another function. This also gives me a chance to show you another JavaScript keyword: return
.
-
Create another function near the top of
main.js
and place it just beneath the function declaration forappendLine()
.New Function const offsetStepA = function(offset) {let step = 'A';let characterCode = step.charCodeAt(0);characterCode += offset; // same as characterCode = characterCode + offset;let text = String.fromCharCode(characterCode);return text;} -
Now, let’s modify our
appendLine()
function.Append Line let step = 0; // A global variable to track our current stepconst appendLine = function(someText) {let letter = `${offsetStepA(step++)}) `;const sandbox = document.querySelector('output#sandbox');sandbox.innerHTML += '<br>';sandbox.innerHTML += someText;sandbox.innerHTML += letter + someText;}When our code runs, you will notice that the letters for the output are duplicated. That’s because we are now calculating the next letter inside of our function.
-
To fix the duplicate step letters, remove the hard-coded step values from each call to
appendLine()
. Here’s the modification of the first call.appendLine('A)There are many assignment operators');appendLine('There are many assignment operators');See if you can complete the remaining corrections.
Our auto-numbering function has further simplified our code by removing the need for us to hard-code each sample output we generate. If you feel uncertain about some parts of the code we just wrote, don’t worry. I’ll make some brief comments and point you to further explanations of how it works.
Conclusion
The final version of our sandbox experiments is complete. Along the way, we’ve practiced the discipline of refactoring and we’ve learned a couple of things about functions in JavaScript. As a bonus, I’ve thrown in a few nuggets of JavaScript syntax and operators through our use of the offsetStepA()
function. They include the following:
++
operator - Author TODO: Linksfunction
+return
keywords - Author TODO: Links- declaring and calling functions - Author TODO: Links
- Use of global variable
step
- Author TODO: Links - Character codes:
.charCodeAt(0)
+String.fromCharCode()
- Author TODO: Links