Skip to content

Lab 03: Introduction to JavaScript

In this lab, you will begin to use JavaScript in making your webpages more dynamic. JavaScript enables users to interact with the webpage's elements (and may also consequently modify the appearance of webpages through a set of action(s)).

Getting Started

There are two methods of implementing JavaScript into your HTML file:

  • embedded style
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JavaScript Example</title>
  </head>
  <body>
    <!-- Body content -->

    <script>
      // JavaScript code here
    </script>
  </body>
</html>
  • external style
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JavaScript Example</title>
  </head>
  <body>
    <!-- Body content -->

    <script src="script_name_here.js"></script>
  </body>
</html>

To implement JavaScript using embedded style, the <script></script> element should be used.

Location of <script> Tags

Unlike CSS, you may use them in either the <head> or <body> section, or both if necessary. The only times when order is necessary is when you require a set of script commands to run first before another set of scripts.

let, const and var

The ECMAScript 2015 (ECMA 6) standard introduces the let and const keywords as better alternatives to var when naming variables. let is used to declare regular variables virtually the same way as how var was the go-to for the same purpose, whilst const introduces a way to create constant variables that cannot be altered upon declaration.

Going forward, let and const should be used instead of var. This is mainly due to their effects on variable declarations. Declaring var is synonymous to declaring a global variable in JavaScript that can easily be modified regardless of context (i.e., in a function vs. outside of a function). By declaring a variable using var, you can expect unwanted changes in your code (basically bugs) and problems revolving scopes (i.e., function scope and block scope).

Refer to the following:

function aRandomFunction() {
  var a = "Red";
  let b = "Blue";

  console.log(a, b); // this prints: "Red Blue"

  {
    // Inside a block (can be for program control statements
    // or practically anything that uses curly parentheses)
    var a = "Green";
    let b = "Yellow";

    // let's assume that variables a and b
    // need to take on a different value temporarily here (for reasons)

    console.log(a, b); // this prints "Green Yellow"
  }

  // Outside of the block now
  console.log(a, b); // this prints "Green Blue",
  // can be a HUGE problem if a needs to be kept as "Red"
}

aRandomFunction(); // statement to invoke above function

By declaring variables using the let keyword, you can ensure that should they need to be temporarily reassigned a different value for only within the block context, it can be done without affecting it's original value outside of said block context. This, being a trait that exists when declaring variables in many other programming languages, is something that var fails to emulate.

Within JavaScript, there exists a global context/object called window which contains a number of important preset values. Think of it as like a large drawing canvas with preset items like a house with a roof of a certain color (e.g., blue). In this instance, let's assume that this window object has one attribute called color. By declaring a variable named color using the var keyword, you're essentially going to modify the default color value, which may be potentially important and will cause quite a ton of problems if tampered illegally. You can view all the attributes/variables of concern if you type out window in the Inspector Console, or simply the following statement line in a JavaScript file:

// Yep, there's a bootload of 'em!
for (let v of Object.keys(window)) document.write(v + "<br>");

The following video also gives a good explanation behind why using var to declare variables in JavaScript can be a BAD idea.

Naming Variables

When naming most things, it is a popular preference to adhere to the Camel Case Naming Convention. This naming convention requires that:

  • all letters in the first word in the name be strictly in lower case, and
  • the first letter in each subsequent word (to be placed without spaces) in upper case

Examples of such names adhering to the Camel Case Naming Convention include: ports, badgerMole, numberOfPots, timeOfDay, sensor1

The other major naming convention, being Pascal Case Naming Convention, should be reserved for naming classes (you will notice this in React classes). This naming convention requires the first letter in ALL words in the name to be upper case, the rest of which are in lower case.

Some of you who may be familiar with Python may have already been introduced to the Snake Case naming convention requiring all letters to be in lower case and underscores (_) to be separate each word in the name (e.g., number_of_snakes, user_input, test_subject_1). This naming convention is also just as acceptable as the Camel Case Naming Convention, though from my point of view, not many use it here for JavaScript.

Naming Constants

Constants are typically named differently, vaguely matching the convention used to name variables in Python with regards to how words are separated with underscores. However, all letters in constants are presented in upper case (e.g., NUMBER_OF_ROUNDS, KILOMETERS_TO_MILES).

Addendum: However, if you are familiar with React, you may find that constants are named in the Camel Case naming convention, similar to regular variables. Additionally, here you will also typically find components named in the Pascal Case naming convention, similar to classes.

Functions

Function declarations in JavaScript follow the given syntax:

function functionNameHere(param_1, param_2, ..., param_n) {

}

The items you include in the round parentheses are referred to as parameters. Sometimes, parameters are required to carry out a function's intended purpose(s). For example, the following function makes use of two number values with intentions to produce the sum after totalling them up.

function addition(number1, number2) {
  // number addition logic here
}

The following function, however, does not require any parameter values to display a greeting message, and thus has no parameters associated with it.

function greeting() {
  console.log("Hello World!");
}

It is imperative to know that there is no such rule that states how many parameters EVERY function needs to have. The number of parameters any function should contain solely lies on any need to depend on any external value(s) to properly carry out its.. well, function.

Sometimes, functions can also be used to return values as the last step in completing their purpose(s). In such cases, a return statement is invoked from the function (not necesarily at the end all the time, but merely a traditional thing). For instance, let's refer to the addition function from earlier again. Upon calculating the sum of the two numbers, depending on how you are to present your output, you can choose to have the function just print the sum out or return it out of the function as a form of output at the line that spawned its use.

Here's how it will look like if the main idea is to solely print out the sum of the two numbers from within the function:

function addition(number1, number2) {
  let sum = number1 + number2;

  console.log(`The sum of the two numbers is ${sum}.`);
}

Here's another variation of the same function, with the main difference being that it returns the sum at the end.

function addition(number1, number2) {
  let sum = number1 + number2;

  return sum; // return statement
}

Admittedly, this may seem relatively confusing as compared to implementing functions in other programming languages like C or Java where one can tell if a function is to return a value or not. For instance, in these two languages the data type of the intended return value is to be explicitly stated in the function declaration itself, or void if it's supposed to not return anything at all. However, just by knowing how you want to craft your function based on the set requirements should be able to provide enough information to keep you going here.

Arrow Function Expressions

Lab Activity

For this lab activity, we are going to focus mostly on simple program outputs. They may not seem significant, but what you will be practicing here will come in handy especially with debugging JavaScript web projects. Don't worry, we'll get to implement some more meaningful logic with JavaScript in the next lab activity.

We will start with a simple HTML webpage template - prepare index.html as follows:

index.html
<html lang="en">
  <head>
    <title>JavaScript Exercise</title>
  </head>
  <body>
    <p>Click on the button to confirm that you have read this page.</p>
    <button id="button1">Click here</button>

    <script type="text/javascript">
      function checkReadPageFunction() {
        alert("I have read this page.");
      }
    </script>
  </body>
</html>

This template currently uses embedded JavaScript, which is perfectly fine for now. Consider relocating the JavaScript code into an external file and linking it to index.html an extra task for this lab activity.

Inside the embedded JavaScript section, you will find a function called checkReadPageFunction() already prepared for you. This function invokes an alert box using alert() - this is one of 3 different pop-up windows that browsers can sometimes show.

Task 1

Right now, the button #button1 does not do anything when clicked. Associate the action of clicking the button to opening up the alert box prepared for you.

Solutions

There are two ways to incorporate this - one of the ways is to add an onclick attribute to button#button1.

<button id="button1" onclick="checkReadPageFunction()">Click here</button>

The other way involves just adding more JavaScript code to modify the HTML DOM elements - if this sounds too abstract to wrap your head around, let me explain..

Notice that the button prepared for you conveniently had an id attribute ready for you? Through using either that or the class attribute, you get to target elements in the HTML page to either obtain or manipulate values inside them - we will dive deeper into those in a future lab activity.

This can be done in one single line:

1
2
3
4
5
function checkReadPageFunction() {
  alert("I have read this page.");
}

document.querySelector("#button1").addEventListener("click", checkReadPageFunction);

Let's break this line down:

  • We use the .querySelector() method to target the HTML element we want to manipulate (in our case, button#button1). You may have been introduced to the .getElementById() method before; this still works, but I prefer .querySelector() as the value you enter is very similar to how you target elements in CSS. The continuity there works in your favor, in case you forget what other kinds of methods you could use.
  • We then chain that method call with .addEventListener(). We use an event listener to link a certain behavior (often by the user) as a trigger for an event to happen. In this case, we want clicking button#button1 to be the trigger to invoke checkReadPageFunction(). This method takes in 2 parameters - the first one is the type of event we want to observe (in this case we enter "click"); the second is what you wish to do, often in the form of a function.

Take note that the second parameter here is checkReadPageFunction and not checkReadPageFunction(). This related to function callbacks, which essentially works a bit like this -

Function Callbacks Example
<html>
  <head>
    <title>Exercise</title>
  </head>
  <body>
    <script type="text/javascript">
      let callback = console.log;
      callback("Hello world");
    </script>
  </body>
</html>

Open the inspector console in the web browser for this one after you enter this in a HTML file with JavaScript in it. A simple right-click on anywhere inside the web browser, and then selecting Inspect should bring it up. Then, click on Console.

You should see the text "Hello world" appear there. The console is a great debugger interface if you ever want to verify values of variables, for instance.

Essentially, the idea is that the variable callback is to be associated with the console.log method, and it is meant to behave the same. If we modified one of the lines such that the JavaScript code is as follows:

let callback = console.log();
callback("Hello world");

You will encounter an error in the console something like as follows:

Uncaught TypeError: callback is not a function
<anonymous> file:///.../index.html:14

This is because entering in console.log() inadvertently invokes the method to run, and in this case since console.log() does not return something to put into callback, this variable does not link to the function. Hence, an error will spawn when you try to use it like a function.

You can learn more about this and about functions in general here:

Task 2

Modify checkReadPageFunction() to display a confirm box (using confirm()) with the text "This will confirm that you have read this page.". Associate the "OK" button with calling the alert box from earlier, and "Cancel" with another alert box with the text "Cancelled.".

Solution

The confirm box is like an alert box, but with some extras. Firstly, you get two buttons in the confirm box - typically they are "OK" and "Cancel". Depending on which one of these two you click, the confirm box returns a Boolean value true if "OK" and false otherwise. We can keep this value in a variable and use it to help determine which alert box to spawn. The first one has already been defined for us, so we just need to include another alert() function call for the other with the appropriate text.

To determine which of the two alert boxes is spawned, we use a decision control structure, namely the if-else clause. We can pair an if statement to checking if the decision is true before spawning the alert box already prepared for us, and the other one otherwise.

1
2
3
4
5
6
7
8
9
function checkReadPageFunction() {
  let decision = confirm("This will confirm that you have read this page.");
  if (decision === true) {
    alert("I have read this page.");
  }
  else {
    alert("Cancelled.")
  }
}

Task 3

Add another <script> element in the <head> section of the webpage. Write a function called greet() which spawns a prompt box asking for the name, which upon clicking "OK" will then spawn another alert box with the text "Hi {name}!", where {name} is what was entered into the prompt box. The prompt box text should be: "Enter your name, please."

The greet() function will then need to be invoked as soon as you load or reload the webpage.

Solution

Inside the <head> section of the webpage, add a new <script> element. Inside said <script> element, create a function greet() along with the appropriate function call like as follows:

function greet() {
  // to complete
}
greet();  // calls greet() function

The prompt box is a little more complex than a confirm box, such that what value the prompt() function returns is not either true or false, but what was entered into the text field provided instead before clicking "OK". If nothing is entered before clicking "OK", the default value is null.

Store that value in a variable, and then use it in an alert() function call.

<head>
  <title>Exercise</title>
  <script type="text/javascript">
    function greet() {
      let name = prompt("Enter your name, please.");
      alert(`Hi ${name}!`);
    }
    greet();
  </script>
</head>

Inside the alert() function call, notice that we used backticks ` instead of quotation marks (' or ") to denote the string value. What we used here is a template literal, which is quite handy in inserting values of variables while making it intuitive to read instead of concatenating multiple strings and/or values traditionally using the + operator. To insert a variable value inside a template literal, you need to use ${<var>} where <var> is the variable whose value you want as part of the template literal.