An introduction to JavaScript
Before we can start writing our first game it would greatly help to get some practice writing lines of JavaScript code. If, at the same time, there is an opportunity to take on board some of the basics of the JavaScript language then this can only enhance the experience. This will help you ease into writing those first few lines of game code. It helps to start with some familiarity with the structure and syntax of our chosen programming language. You can also refer back to this section when typing in some code using an unfamiliar feature although, hopefully, new things will be explained as they are introduced.
Before we get properly started, fire up your Chrome browser if it is not already running, open a new tab and then hit the F12 key to open the developer tools on Windows or Linux. Apple Mac users need to press <alt><cmd><j> (alt command j). On Chromebook use <ctrl><shift><j>. Alternately, use the browser menu option “More tools”, “Developer Tools” in all versions. Then click the snippets tab and click the “+ New snippet” option ready to try out some code. By the way, you have the option of docking the developer window in different positions within and around the browser window.

If the snippets tab is not immediately obvious; click the sources tab at the top of the Developer Tools window and then the chevron next to the Page or Filesystem tab that opens just below. That will open a pop-up list where you can select Snippets. You can then click “New snippet” to open a snippet window.
If you get completely stumped (as the snippets window has got progressively harder to find over time) then this page will reveal the current "secret".

Try typing the two lines in the box below into the snippets window and hitting the Run icon which looks like this:

The two lines are known as “statements” and each statement ends with a semicolon. JavaScript is “case sensitive” so try and ensure that you type in the lines exactly as shown. The box around the two lines of code indicate that this is some code you might like to enter and maybe run. You will see code sections like this a lot in this book.
var j = "Hello World"; alert(j);
Take care to get the lines correctly entered and the browser window should show a pop-up like:

The important bit is the message – “Hello World” (the first line may vary).
Now click the OK button and then type two forward slashes before the line in the snippets window that reads “alert(j);” and then add two new lines. Notice that the second line is now shown in a different colour.
The four lines together should now look something like:
var j = "Hello World"; //alert(j); j = 21; alert(j + 2);
When you click the Run icon (or use the keyboard shortcut
The first line typed in started with the word “var”. This indicated that the line was going to create a new variable. A lot of what we do with programming languages involves storing and manipulating values and the values are stored in variables. The word variable implies that the stored value can be changed (varied). Each variable has a name chosen by the programmer. In the case of this first line the name is just the single letter j. When we create a new variable we can, if we want, assign it an initial value. The first line includes an equals sign and this is the JavaScript assignment operator. The assignment operator sets the variable to the left of the sign equal to the value on the right. In this case the value is what we programmers call a string which is a sequence of characters. A string is enclosed within a pair of quote marks. These can be a pair of single or double quotes with double quotes preferred.
The second line originally read alert(j);. This line caused something called a function (because it carries out a task) that belongs to the browser to display the value stored in the variable j in a pop-up window. We call such pop-up windows dialogue boxes and this dialogue box was closed by clicking the OK button.
We continued by typing two forward slash characters into the start of the second line. This marked the line as a comment. Comments are ignored even when they otherwise contain program code. Comments are generally used to explain what a particular code section is doing which is something that can be very useful when you return to a program after a period of time. Comments can also be used to temporarily exclude a line of code – just as it was used here.
When we added a third line, we did something that you would not be able to do in most computer programming languages. We changed the value stored in the variable j from a string to a number. We proved it was now a number with the fourth and final line. The line passed what we call an “expression” (in this case j + 2) to the alert function. When you ran that code, you saw that the expression was evaluated, 2 was added to the value stored in j and the combined total displayed by the alert function.
Now is probably the moment to describe some of the more important features of JavaScript. We can include plenty more sample code as we go along. Do type in and run as much as you can as this will help you remember and understand the JavaScript as it is introduced.
Variables
Numbers, strings and a whole host of other things are stored in JavaScript variables. Variables are commonly created using the var keyword. It is possible to create new variables without the var keyword just by assigning a named variable a value. In the early days of JavaScript this was a normal approach but this feature is now considered one of the bad things about the language, so we will avoid it. Variables are given a name. A JavaScript variable name can contain letters, numbers and the symbols $ and _ (underscore). Variable names should always start with a letter although that is a somewhat broad church as JavaScript supports Unicode so (in theory) a variable name could use Japanese Hiragana or Katakana script characters alongside a great many others. There is a convention though that JavaScript programmers should stick to English alphabetic characters for variable names which is great for those who can read this book. JavaScript variable names cannot be the same as JavaScript reserved words (the language keywords plus a few held in reserve) as that would confuse things.
Remember that JavaScript is case sensitive so a variable named myNumber is not the same variable as mynumber. Both can happily exist side by side although this might well confuse anyone (well me, certainly) trying to make sense of the code.
Variables can be used to store strings and numbers as we have seen. They can also hold the special values true and false as well as things called objects that can themselves contain multiple named values and even functions.
In fact, JavaScript variables are themselves objects although for the most part it is fine to just think of them as labels for bits of computer memory that allow you to make use of their stored values, whatever type those values might be.
Operators
We have already met the familiar + arithmetic operator and the = assignment operator.
Arithmetic Operators
The set of JavaScript arithmetic operators also includes minus -, multiply *, divide / and modulo %. Programming languages do not use an x as a multiplication operator as x is usually a valid variable name. The forward slash is used for the division operator as there is no traditional division sign (÷) on PC keyboards.
The modulo operator computes a remainder when one number is divided by another. Try adding the following lines to the end of your code in the Snippets window.
j = j % 5; alert(j);
When you give the code a run you should see the second result displayed is 1. This is because 21 (j is still 21) divided by 5 is 4 remainder 1.
Just as in school arithmetic we can use brackets to change the order of precedence when evaluating an arithmetic expression.
To illustrate that, try two new lines of code:
alert(3 + 4 * 2); alert((3+4) * 2);
There are two additional arithmetic operators, increment ++ and decrement - - (plus plus and minus minus). Before we try them, comment out all of the existing lines that call the alert() function with two forward slashes.
Then add another four new lines to your Snippets code:
j++; alert(j); j--; alert(j);
When run you should see that j is incremented to 2 and then decremented to 1.
It should be pointed out that JavaScript numbers are stored as real numbers (binary representations of decimal fractions) in a format with a fixed size. If you look it up on the Internet you should find out that the format is 64 bit floating point. The range of possible values is very large but very large or very small numbers and some fractions can be said to have “low precision”. Particular care should be taken when comparing fractional values as this lack of precision could lead to unexpected errors. Try this in the Snippets window:
alert(0.1 + 0.2);
Normally, four millionths of a millionth of a millionth are of no consequence but try:
alert(0.1 + 0.2 === 0.3);
Comparison Operators
We often need our program code to compare two values. We can start with the equality operators. You will remember that the = sign was already in use as an assignment operator so we test for equality with == and ===. [That was two equals signs together and then three equals signs.] Why two operators? Well three more lines of code will explain why. You might want to go back and “comment out” the last two lines that used the alert function.
Now add the three new lines.
var a = "1"; alert(a == j); alert(a === j);
The first line adds a new variable and assigns it a string value – just a single character “1” (one). When you run the code, you should see that the first comparison between the values number 1 and the string “1” is deemed true and the second comparison is deemed false.
The first comparison (using ==) returned true as the two values held in the variables could be the same if one was converted to the same type as the other. The second comparison (using ===) was more exact and returned false because the two values were not exactly the same.
While the == comparison operator might seem to be a powerful feature it is nowadays considered to be another one of those bad bits. We should endeavour to only use === as this will almost always match our intention. If I slip up in this book then please let me know.
There are also two similar inequality operators. Try changing the last two lines in your Snippets code window to read:
alert(a != j); alert(a !== j);
Those lines are using the exclamation mark (sometimes called shriek).
Now when you now run the code the first alert shows false and the second true. Both tests assert that a is not equal to j. The first result is false because a could equal j if one value type was converted to the other while the second test proves true as, in a stricter sense, a is not equal to j. Again we will resolve to only use !== as that will protect us from any surprises when our code is run.
There are some other comparison operators.
Comparison Operator Description | Operator | Description |
Less than | < | Compares two values and returns true if the first is less than the second. Otherwise false. |
Greater than | > | Compares two values and returns true if the first is greater than the second. Otherwise false. |
Less than or equal to | <= | Returns true if the first value is less than or equal to the second, otherwise returns false. |
Greater than or equal to | >= | Returns true if the first value is greater than or equal to the second, otherwise returns false. |
You might well wonder how these comparisons manage when the values being compared might be a mix of numbers and strings. I have noted how JavaScript copes with such comparisons here in case you need to refer back at some point.
If the two values being compared (strictly these are call operands) are numbers or can be converted to numbers then the comparison is numeric.
If both operands are strings or are best converted to strings then they are compared as strings (“a” being less than “z” for instance although it is slightly more complicated than that).
If one operand is a string or can be converted to a string and the other is a number or can be converted to a number then JavaScript attempts to convert the string to a number and do a numeric comparison. If the string can’t be converted then it is given a value of NaN (which stands for “not a number”) and most comparisons will be evaluated as false.
If the operands can’t be converted to a number or a string then the comparison will always be evaluated as not equal.
We usually come across comparison operators being used by an “if” statement. We will get to those shortly but first logical operators so we are fully equipped.
Logical Operators
Sometimes we want to know if two or more things are true at the same time so we have a logical
It is probably time to delete all of the lines currently in the Snippets window and start again with the following:
var a = 3; var b = 7; var c = 54; alert(a < b && b < 6); alert(a < b && b < c);
If you run this you should see that the first expression passed to the alert function returns false as while a is less than b, b is not less than 6. The second expression evaluates to true as both a is less than b and b is less than c.
We might also want to know if one or other (maybe both) of two conditions is true. To do this we use the
Try replacing the && operator with the || operator in the Snippets code window and running the JavaScript again.
alert(a < b || b < 6); alert(a < b || b < c);
You will see that both expressions evaluate to true. In the first instance just one of the comparisons is true and in the second both are true.
Just one more for the moment. This is the
You could try changing the last two lines of your code to read:
alert(a >= b); alert(!(a >= b));
The first expression evaluates to false as a is not greater than or equal to b. The second returns true as the NOT operator flips the logic. It evaluates to “not false”, which is true. You could have written the last code line (complete code lines are also known as a statements) as:
alert((a >= b) === false);
It is true that (a >= b) is false so the whole expression that compares that false result to false evaluates to true. I do hope that is not confusing.
You may also have noticed that I used brackets within some of these code lines (statements) to group parts of an expression together so that they are evaluated first – just like using brackets in an arithmetic expression.
Now to see what we really do with the comparison operators. We most frequently use them with if statements.
The if Statement
A simple if statement looks like this:
if(a < b){ alert("We have less apples than bananas"); }
The format is the word
If you want to run some alternate lines of code if the if statement condition proves false then you can use an else clause. Don’t bother running the next few examples, just take a look at how they are written.
if(a < b){ alert("We have less apples than bananas"); } else { alert("There are at least as many apples as bananas"); }
If a is not less than b the code between the curly braces following the
You can even write something like:
if(a < b){ alert("We have less apples than bananas"); } else if(a === b) { alert("There are equal numbers of apples and bananas"); } else { alert("There are more apples than bananas"); }
Our games are going to include a lot of if statements so we will get plenty of practice with them.
If we are dealing with a condition a bit more complex than the content of a fruit bowl, we might be tempted to write something like:
if(a === 1){ // do something } else if(a === 2){ // do something a bit different } else if(a === 3){ // something different again } else {// do something else}
Fortunately, JavaScript has a different approach to handling lots of conditions based upon the value of a single variable or the result of an evaluated expression.
The switch Statement
switch (a) { case 1: // do something break; case 2: //do something a bit different break; case 3: // keep going break; default: // what we do when none of the other cases match // (this is optional) }
The value of a variable or an expression within the brackets after the switch keyword is matched to a list of cases. The case matching uses strict (===) comparisons by the way. If a match is found then all of the following lines of code are executed until a break statement or the closing curly brace is encountered. If no match is found then JavaScript looks for an optional “default” and executes the code following the default case if one is found.
Again, switch statements are going to come up as we develop our games so you will get some practice writing and running them.
There is a third type of statement that is used to manage conditional code. This statement type includes what is known as a conditional or ternary operator.
The conditional operator (?:)
The format is broadly (condition)
You could sneak this next code block into your Snippets window so it looks like:
var a = 3; var b = 7; var c = 54; alert(b <= 10 ? "We have less than 10 bananas" : "We have many bananas");
That one you might like to try running. If you try a couple of values for the variable b you should be able to see both possible results. Did you notice that the last statement in that code block ran over two lines? That was fine as JavaScript could tell that the fourth statement was not complete at the line end. The final semicolon on the fifth line unambiguously terminated the statement.
Again, the conditional or ternary operator is going to get some work while we write our games. Now we are back on operators we had better run through the other types.
String Operators
If numbers get arithmetic and comparison operators, what do strings get?
Well the comparison operators we have already covered are also used for strings. Strings also get the +, concatenation operator. The concatenation operator can be used to join two strings together.
Once again, delete all of the current code in your Snippets window and start again with these three lines.
var a = "Hello"; var b = " new programmer"; alert(a + b);
You should see the nicely joined up message displayed in the pop-up dialogue.
The string + operator can also be used to convert numbers to strings as part of the concatenation process. Try changing the code to read:
var a = 3; var b = " deadly sins"; var c = a + 4 + b; alert(c);
and when it is run, you should see that c now contains the string “7 deadly sins”.
You need to watch the order of the terms (operands) involved though as the following line should demonstrate:
alert("Deadly sins: " + 3 + 4);
Give it a whirl and see what happens.
If we concatenate a number to a string then the number is changed to a string. In the instance above that was done in two steps with 3 being converted to a string and concatenated to the first string. Then, when the second + operator was reached, the same happened to the number 4. In the first example, the first + operator was treated as an arithmetic addition and only the second as a concatenation operator.
Compound Operators
Compound operators are a form of shorthand for JavaScript code and we will run into these useful extras.
Compound Operator | Example | Short for |
+= | a += b; | a = a + b; |
-= | a -= b; | a = a – b; |
*= | a *= 2; | a = a * 2; |
/= | a /= 3; | a = a / 3; |
%= | a %= 5; | a = a % 5; |
Functions
We are going to write a lot of functions. Functions are (normally) named blocks of code that carry out a specific task. Commonly, a function will return a value as a result of that process. Functions may be passed values to use in any processing and these values are called arguments.
A function is most often defined using the “function” keyword.
function square(a){ a *= a; // square the value return a; }
Here a function called square has been defined. The function takes a single argument and assuming the argument to be numeric, attempts to multiply the number by itself. The result of that calculation (note the use of the compound operator) is returned to any code that calls the function.
We could try this out by deleting all of the code in the Snippets window and replacing it with:
var a = 7; var b = square(a); alert(b); function square(a){ a *= a; // square the value return a; }
Give it a run and you should see the value returned by the function and stored in the variable b is 49.
“Hang on!” you might reasonably say. “The function argument has been given the name “a” and that is the same as the variable created in the first line.” So, is there a conflict? We can test that with an extra line placed before the function definition.
var a = 7; var b = square(a); alert(b); alert(a); function square(a){ a *= a; // square the value return a; }
This should confirm for you that the original variable a is unchanged by the internal processing of the function. The function argument a is said to have only “local scope”. You can think of it as only existing within that function. However, functions can make use of external variables if those variables have a wider scope. It is worth typing in and running the following code as it is important to understand which variables are accessible to a function.
var a = 7; var b = 6; alert(adams(a)); function adams(a){ a *= b; // multiply the local a by the external b return a; }
You should see that the function returns a value of 42.
Now, change the function to read as follows:
function adams(a){ var b = 2; a *= b; // multiply local a by local b return a; }
Here you should see that the variable b inside the function is “masking” the external variable b with the result that the calculation adams(a) now returns 14.
Some purists would argue that functions should never make use of any variable not passed as an argument. There is something to be said for this except where we want the function to change the value of one or more external variable – this often happens in our game code as you will see.
The line “var b = 2;” used in the function above should have been written “let b = 2;”.
The
Functions have many interesting tricks up their sleeves but we will defer exploring some of those until we are further into the book. We have a few other key components to introduce although I am sure you are keen to start programming the first game.
Arrays
It is very common when programming to have lists of things. It is very convenient if those lists have a single name with individual members of the list being addressed using (say) an index number. As in most programming languages, such lists are implemented in JavaScript as an array.
var myArray = [1,2,3,4,5,6];
The variable myArray (as usual, any valid variable name is fine) has been defined as an array containing 6 numbers. Their array index values run from 0 to 5. The value at myArray[0] is 1 and the value at myArray[5] is 6. We programmers just about always start counting from zero as (surprising as this seems at first) this usually simplifies our code.
We can create an array of strings or objects or even mix numbers, strings and objects within an array.
We can create an empty array and then use the push() function to add elements to it.
var myArray = []; myArray.push(3); myArray.push(7);
The first line creates a new (empty) array and the next two lines push two new values into that array. The value at index position 0 will be 3 with the 7 sitting at index position 1.
Later in the book you will meet two dimensional arrays (arrays that contain arrays) and arrays of objects plus there is a reference chapter on the JavaScript built in objects like Array, Math and Date towards the end of the book.
One of the things we often want to do with an array is run some code against each element in turn. One way of managing that (and other repetitions) is with a for loop.
The for loop
The for loop is used to execute a code section a fixed number of times or until a specific condition is met. There is an example of most common usage together with some test code to try this loop out below:
let total = 0; for(let i = 0; i < 10; i++){ total += i; } alert(total);
This loop is executed 10 times incrementing the variable i after each run through the code enclosed within the loop curly brace pair. When the variable i reached a value of 10 then the loop terminated as i was no longer less than 10.
The three controlling parts of the for loop statement are separated by semicolons. The first section was used to initialise a counter variable (i is very traditional). The second section set the condition for ending the loop. The last section was used to increment the counter variable.
Arrays have a useful property called length which holds the count of elements in the array. We can illustrate how this might be used in a for loop with the following code that counts the number of vowels in an array of letters called chars.
var chars = ["a","b","c","d","e","f","g","h","i"]; var vowels = ["a","e","i","o","u"]; var vCount = 0; for(let i = 0; i < chars.length; i++){ for(let j = 0; j < vowels.length; j++){ if(chars[i] === vowels[j]){ vCount++; break; } } } alert("There were " + vCount + " vowels in the list");
The code has two for loops to run through the arrays counting up the characters in chars that match one of the list of vowels. When a match is found, the variable vCount is incremented and then we hit something we have met before in the switch statement – a break statement. The break keyword can be used to exit a for loop before it has reached the end. The quick exit is only for the inner loop that contains the break statement and the outer loop through the chars array continues.
There are two other statement types that control loops. The first is the more common and is known as the “while loop”. The format is straightforward:
while(some condition is true){ // these code lines are executed }
The while loop terminates when the condition enclosed within brackets after the while keyword evaluates to false or a break statement is encountered.
The second format is known as a do loop where the condition that decides if the loop should continue to be executed sits at the bottom of the loop.
do { // the enclosed code statements are executed } while(some condition is true);
The code within a do loop is always executed at least once. You can think of it enclosing some code that you always want to run but that can be repeated subject to the control of the final while expression. Plus note the terminating semicolon that was not required by the other two loop formats.
Objects
Objects are a fundamental datatype in JavaScript. Instead of representing a single number or string they can hold a collection of values and sometimes even functions.
You can define a new object variable with object “members” and values placed within a pair of curly braces and separated by commas.
var myRectangle = { top: 0, left: 0, width: 48, height: 36 }; alert("Rectangle size: " + myRectangle.width * myRectangle.height);
The alert statement also illustrates how to access an object’s members using “dot” notation. The dot separates the object name from the member name.
As an object is a variable, we can change any of the values it contains.
var myRectangle = { top: 0, left: 0, width: 48, height: 36 }; myRectangle.width = 50; alert("Rectangle size: " + myRectangle.width * myRectangle.height);
We can even add to the list of members when a program is running.
myRectangle.colour = "red"; alert("Rectangle colour: " + myRectangle.colour);
This, sometimes useful, feature has the slight downside that if you miss-spell a member name in your code when assigning it a value you can end up adding a new member instead of setting the value of an existing one.
In addition to the “dot” notation already used you can treat an object as if it was an array but with the member names acting as the array element index value. (An array of this type is known as an “associative array”.) However, the “dot” notation is preferred in most circumstances.
alert("Rectangle width: " + myRectangle["width"]);
If your program needs to create more than one copy (instance) of the same object then you can use a function to define the object and use the “new” keyword to create each instance. You can even pass the function some arguments to help initialise each instance.
var Rectangle = function(width, height) { this.top = 0; this.left = 0; this.width = width; this.height = height; }; var rect1 = new Rectangle(24, 12); var rect2 = new Rectangle(36,15); rect2.top = 124;
The object building function introduces a new keyword – “this”. The this keyword is used to refer to the members of that particular instance of the object.
When we pass values like numbers or strings into a function as an argument then they are treated as local values within that function. Changing such an argument value has no effect upon the external value passed to the function. This is not true for objects. If an object name is passed into a function as an argument then changes to the object within that function are also made to the original object that is external to that function. This can be a very useful feature but it can lead to inadvertent bugs.
We will be creating many objects within our games. Some objects will collect together closely related values and others will represent key game components such as sprites.
The Boolean data type, true and false
When we looked at the comparison operators and later at the if statement, we got used to the idea that an expression could be resolved to be true or false. We have also taken on board that JavaScript is pretty relaxed about comparing different data types and will happily “convert” one type to another.
The JavaScript Boolean data type has just the two possible values – true and false. If a Boolean value is converted to a number, then true becomes 1 and false 0. When we used the alert function to display the results of a comparison, we saw that the word “true” or “false” was displayed. This is because when a Boolean value is converted to a string, the result is the word “true” or “false”.
If we treat any number as if it was a Boolean data type with an if statement:
var n = 23; if(n) { alert(true); } else { alert(false); }
The code would convert the value in n to a Boolean and then display the result. You can have a play with some different initial values for n. You should find that the value 0 (zero) is false and that all other numeric values are true. You can also add some code to check that an empty string (or one with just a space character) is false and all other strings are true.
There is also special JavaScript keyword – null. The value null is used to indicate an absence of any value and is often used as a placeholder for an object before it is initialised (as you will see later in the book). When converted to a Boolean, null resolves happily to false.
Are we nearly there yet?
Short answer yes. You have now taken on board a lot of JavaScript. Certainly, enough to start programming some games. Please bear in mind though that none of the little introductions to the language features has been complete. There is a lot more to learn. JavaScript has an astonishing capability that I hope you go on to fully enjoy. Oh, and there are also some strange pitfalls that you need to avoid. Like any programming language, it has its flaws but wow, can you get things done!