GEOG5870/1M: Web-based GIS A course on web-based mapping

Language elements

By tradition, the first example program shown for computer languages is one called 'Hello World', which simply writes the message 'hello world' to some type of output; it is the simplest thing that shows a program/computer is working. Figure 1 shows the source of a simple web page which contains a JavaScript 'hello world' program.

<html>
<head>
<title>A simple web page</title>
<script type="text/javascript">
alert("Hello world!");
</script>
</head>

<body>
Page body text
</body>

</html>

A copy of the resulting program can be seen here.

We'll consider later on the way in which this code is embedded in the web page, and look first at the fundamentals of the language. The 'hello world' program consists of the single line: alert("Hello world!");, all the rest of the code is the HTML page that contains that short program.

Code layout and format

Case sensitivity

JavaScript is a case sensitive language. Our 'hello world' program used the function alert(); if we'd written it as 'ALERT()', or 'Alert()', the program would not have worked, as the function would not have been recognised. Similarly, when we come to use variables, it is important to note that 'x' and 'X' are different variables.

Whitespace

JavaScript largely ignores extra whitespace (spaces, tabs, line breaks), which means that you can format you code with whatever pattern of spacing and indentation that you like. Clear spacing and indentation can help to make the code more readable and make the purpose clear. Note, however, that developers will quite often compress entire libraries onto one line, in part to obfuscate how code works (by its very nature, JavaScript code will usually be publicly available), and in part to remove extra characters and shrink file sizes. This is definitely not recommended practice, and for this course we expect all code to be clearly laid out.

Line terminators

All statements (roughly speaking, the same thing as 'a line of code') should be ended with the semicolon character ';', as in our example above. As noted in the introduction, JavaScript was designed to be forgiving, and one example of this is that line terminators can be omitted; however it is considered sloppy practice to do this, and it is possible to write ambiguous code if you rely on JavaScript to 'do the right thing' when you leave line endings out.

Comments

All programs - whatever language they are written in – should contains comments. Comments are messages to a human reader that explain what is going on in the program. JavaScript recognises a number of different comment styles. Single line comments start with '//' – anything after that will be ignored. Longer multi-line comments can be placed between the opening characters '/*' and the closing characters '*/'. Examples of different comment styles are shown below.

// This is a single line comment

i = 1; // Comments can also be placed after some code

/* This is a
multi-line
comment */

/*
 * People often
 * format
 * multi-line comments like this
 */

/* This comment uses multi-line format */

Identifiers, literals and reserved words

An identifier is a name of a data item, such as a variable, array of function, whilst a literal is a fixed value that is not going to change (though you can obviously change the literal associated with a variable, including those inside "object literals"). In the second comment example above, the sample code 'i = 1;' contains an example of a variable which has the identifier i and a literal value, 1.

There are some simple rules that govern the names that can be used for identifiers. The first character must be an uppercase or lowercase letter, or a dollar sign ( $ ) or the underscore character ( _ ). The remainder can be any mixture of letters, numbers, dollar signs or underscore characters. A final restriction is that identifiers cannot be one of the reserved words in JavaScript. Reserved words are keywords that are used as commands and in-built functions, clearly a program that used such terms as variable names would be very confusing. Current reserved words are listed below, including some that have been specified in the Ecma standard as reserved for possible future use in JavaScript. You do not need to memorise these lists, just to be aware that reserved words exist, and that you should choose variable names appropriately. If your code is behaving unexpectedly, (or generally, failing to run), it may be worth checking that you have not tried to use a reserved word as an identifier.

JavaScript reserved words: break, case, catch, continue, default, delete, do, else, false, finally, for, function, if, in, instanceof, new, null, return, switch, this, throw, true, try, typeof, var, void, while, with

Ecma reserved words (for possible future use): abstract, boolean, byte, char, class, const, debugger, double, enum, export, extends, final, float, goto, implements, import, int, interface, long, native, ackage, private, protected, public, short, static, super, synchronized, throws, transient, volatile,

Data types and values

Having discussed the code format and layout, we can now look more closely at what goes in to the program. The first area to look at is data types – what sorts of variables and other data items we can use. JavaScript supports a number of primitive (basic) types, plus more sophisticated composite types (linking several primitives together). Primitive data types are numbers (with no distinction between integers/whole numbers or floating point/decimal numbers), text strings (a series of characters), and boolean values (that can have the value either 'true' or 'false'). Composite types include arrays – collections of primitive types – and objects – which incorporate both data items and code that acts on those data items (see below). JavaScript includes a number of built in specialised objects, including for example, objects representing the browser window and the current document.

Variable declaration

New variables must be declared using the keyword 'var', for example: var i; or var i = 1;. In the former case the variable has been created but is not yet defined, in the latter case we have both declared it and initialised it (given it a value).

Numbers

Numbers can be represented in various forms in JavaScript – integers, floating point values and octal (base 8) or hexadecimal (base 16) values. Basic operations occur as you might expect, using +, -, * and /, for example 'i = i + 1;' or 'x = y * z;'. More advanced functions are available through the Math object; for example 'x = Math.sqrt(y);'. Here, we are calculating x as the square root of y, using the sqrt() method of the Math object. We will learn more about objects and methods below.

Strings

A string is a sequence of characters – letters, digits, punctuation marks and so on. Strings must be placed within quotes, using either single or double quote characters.

Strings can be joined using the '+' operator, for example: mesg = 'Hello ' + 'world!';

Boolean values

The Boolean data type has only two possible values: true or false. You will most commonly come across these implicitly (i.e. they won't be named variables) as the result of logical comparisons. Consider the code fragment:

if (x > y)
   a = a + 1;
else
   b = b + 1;

In the first line, we make a comparison between two values, x and y, and then specify two alternative things for the program to do depending on their relative values. The comparison gives a result that is either true or false; this is a Boolean value.

Objects

An object is a composite data type that includes several named data items, that are usually referred to as properties of the object. We can refer to the properties of an object using the syntax object_name.property_name. Thus, if we had an object called point, we might refer to the properties point.x and point.y. Objects can also contain code that does specific jobs, usually associated with the data in the object. These are called methods if associated with objects (though more generally these code chunks are called functions). We'll come back to these in more detail later, as there are some oddities about them that you don't see in other languages.

Methods usually act on the properties of the object (or on data passed in as a method parameter). We saw an example of this in the description of numbers above: sqrt() is a method that is part of the Math object, and we passed in the variable y for it to work on. It returned to us the result, which we put in the x variable:

x = Math.sqrt(y);

Methods are access in the same manner as properties, using the syntax object_name.method_name() (note the parentheses to denote a method rather than a variable, and to allow data to be passed in).

The properties of an object can be data items, methods/functions, or other object types. The fact that an object property can itself be an object means that you will see pieces of JavaScript code with multiple full stops ("chaining"), like this:

document.myform.button

Here, we are referring to button, which is a property of the object myform, which in turn is a property of the object document. Equally, we can throw in method calls, like this:

document.mymethod().buttonClick()

i.e. run document.mymethod(), and whatever comes back from that method call, call its buttonClick method. Such chaining is very common in scripting languages, because it is easy to cut and paste without understanding and it avoids accidentally leaving out chunks of code. It is more concise than:

var a = document;
b = a.mymethod();
c = b.buttonClick();

and creates less unnecessary variables (and is therefore more efficient). However, on the negative side, if something doesn't work, it is often hard to tell where it is failing, and you may need to expand the code like the above to find the error in a specific line.

Objects have to be made using the new operator, like this:

Here, i is being declared as a new generic object, to which we can attach properties and methods, whilst myDate is being declared as an instance of the specialised built in object Date..

Arrays

A regular array is a specialised object which contains a set of data values which can be referred to by index values, starting at 0. This if we have an array x, then x[0] refers to the first value in the array, x[1] to the second value, and so on. As they are objects, arrays are also declared using the new operator:

We can also declare arrays using a special array notation:

Arrays can contain any data types, including other arrays, thus we can create matrices like this:

Here, we have created an array called myMatrix, using the [] notation. It contains three elements, each of which is an array, again declared using the array notation. We can refer to elements of this matrix, for example myMatrix[1][2] refers to the third element (since we start counting at zero!) of the second value (the array [4,5,6]) in myMatrix.

Since arrays are specialised objects, they can have methods as well as the value properties. The Array() object is a specially defined object, that has a number of built in methods and properties, including 'sort()' and 'length'. The property length indicates how many elements the array has, and will change as more elements are added to the array. The method sort, as you might expect, sorts the array. (Something that is less obvious is that by default 'sort()' uses dictionary order sorting, even if the values are all numbers. However, alternate sorting functions can be provided). Whereas the length property returns a value when inspected, the sort() method acts on the data in the array. Thus, we can use them like this:

Functions

Most modern languages are procedural, that is, they are structured into procedures (in Java, methods; Python, functions): useful chunks of code that can be called to do a job, before the code execution returns to the calling point. In JavaScript, these structures are called functions (though in objects, when named, you may find them called methods &ndash see above). An unusual aspect of JavaScript is that functions can be considered akin to variables in most contexts, so we can attach variable names to functions, as we do, for example, in:

<BODY onload="initialize()">

This extends to treating functions like variables more generally, so, for example, you can hold a function in an array, or pass it into another function.

Functions are defined using the function keyword and return results to the calling code using return. The code below shows a simple function.

function square(x) {
   return x*x;
}

This creates a function called square, which will return the square of its input parameter. We would use it like this:

This code also illustrates an important part of the syntax of JavaScript (and all C-like languages), that the curly brackets '{}' are used to group together a series of statements. In this example the function consists of only one line; most functions are more complex and require several (possibly many) lines, and the brackets indicate where the function code starts and ends.

One final thing on functions; note that occasionally we want to set up a function without a name. The syntax for this is:

function () {
   // stuff done
}

This may seem strange, but it allows us to do stuff like this:

var f = function () {
   // stuff done
}

or

someFunction(function () {
   // stuff done in function passed as a parameter
})

Operators

The examples above have a contained a few examples of operators, tokens in the code which make the program do some sort of operation on data items. Thus, we have seen that number data types can be manipulated with the basic arithmetic operators +, -, * and /. There are many other operators in JavaScript; we have already seen the 'new' and '.' operators that are used with objects, and the '[]' operator that is used with arrays. It is beyond the scope of this introduction to go through all operators in turn, but it is important to introduce a few commonly used ones.

Two of the most commonly used – and most commonly confused – operators are the assignment operator '=' and the test for equality '=='. The assignment operator is used when we assign a value to variables.

The test for equality is used in comparisons – usually in 'if' statements – to check whether two values are the same, for example:

if (x==y)
   a = a + 1;
else
   b = b + 1;

A very easy mistake is to write the first line in this fragment as 'if (x=y)'. After all, this makes sense in English and maths. This is not necessarily a bug – it is valid code – although it is almost never what you intended. As '=' is the assignment operator, this expression would first set x to be equal to the current value of y. The operator would then return a value of 'true', indicating that it had successfully carried out the assignment operation. The true state would then cause the 'if' statement to be validly interpreted, and the first alternative action would be taken.

A final pair of operators that should be mentioned in any brief introduction are '++' and '--'. These are special unary operators (meaning, they act on a single item) which increment or decrement a variable by one. You will see them commonly used, especially in loop counters:

Variable scope

So far, this introduction has covered lexical issues (rules for the format of the program and what characters and terms can be used), and data types. The final part of this section discusses variable scope. The scope of a variable indicates the different parts of a program in which its value is defined. Variables defined within a function are local to that function, and thus have no meaning when we leave the function to return to the rest of the code. By contrast, a variable defined in the main body of the program is termed a global variable. As the name suggests global variables are defined throughout the program, and thus functions can 'see' the values of global variables. The code below illustrates this.

// A function
function circleArea(j) {
   var i; // local scope
   i = pi * (j * 2);
   return i;
}

// Main program
var pi = 3.14; // global scope
var radius;
var area;

radius = 5;
area = circleArea(radius);
document.write("Radius:" + radius + " Area:" + area);

The program uses a function to calculate the area of a circle. It illustrates a number of features. We have used the variables i and j in the function. j takes the value of 'radius' that is passed in by the main program. The function calculates the answer as i. The variable pi was defined in the main program and thus has global scope; it can therefore be used in the function. The variable i is defined within the function, and has local scope; we cannot see the value of this once we return to the main program; instead we set the variable area to the value returned by the function. In fact, we could have used different variables called radius and area in our function as well as in the main program.

If a function has local variables (declared using the var statement) that have the same name as global variables, they will take precedence in the function. When we return to the main program, we return to our original versions of the variables, which will have retained their values, regardless of what might have happened in the function. In contrast, if we refer to a variable without declaring it in the function, we'll use (and possibly modify) the global variable of that name. Clearly, it is fairly easy to make mistakes with scope, and to unintentionally over-write the original value of global variables.

Finally, it may be noted that the program uses the write() method of the special object document (which is always defined and available) to print a message to the screen.

Javascript joke: Why do C# and Java developers keep breaking their keyboards? Answer: Because they use a strongly typed language (ahahhahahahahahaha!): Source ElijahManor


[ Next: Statements ]
[Course Index]