How did you do that?

If you visited this page from the previous one and you filled in your name as requested, then the page should start with a personalised greeting. (If you wandered in from somewhere on the net, then there will be no greeting, and if you clicked on the reference at the top of the first page - well, perhaps you should try that out sometime)!

How did we do this? Well, there were three components:

  1. You filled in your name and clicked on a button;
  2. Your name was magically transferred to this page; and
  3. We wrote your name (and a 'Hello') at the top of the page!

Let's look at each of these in turn:

1. Filling in information

To do this, we used very simple code to create a form, thus:

A really rather useless form!
<FORM name='myform'> 
      What is your name?  
       <input type="text" name="yourName" size="30"> 
       <input type="reset" onClick='GoThere(myform.yourName)'
          value="Visit the next tutorial page">
</FORM> 

See how this is structured. We have plain old text that asks "What is your name?", followed by two form controls, a "text" input that merely creates a text box that you can type into, and a "reset" button. We use the text input - we've called it 'yourName' - to obtain information. There is no "submit" button, as we would normally expect in a form, and as you will soon find out, we abuse the reset button terribly!

But wait a minute! What's this GoThere function within the reset button? Is this something that is mysteriously defined inside JavaScript? No ways! If you were to go back to the previous page and look at the source code (don't do so just yet), then hidden in the body of the html code you would find something like the following:

A hidden function
  <script language='JavaScript'> 
    <!-- 
   function GoThere(yourname) 
        { 
        location="part2j.htm" + "#" + yourname.value; 
        } 
   //--> 
  </script> 

This is the mysterious hidden function that transforms our useless form into something rather useful. How does it work?

Well, the first thing to note is that when we click on the reset button, something happens. Javascript detects that we have clicked, in other words, than an event has occurred. And because we have inserted the magical invocation

OnClick='GoThere(myform.yourName)'

into the code for the reset button, JavaScript knows what to do .. it looks for the function GoThere, wakes it up, and passes it the information (contained in parenthesis). What is that information? Well, we've called the form myform, and we helpfully labelled the text input within the form yourName, so it doesn't take much imagination to work out that when we click on the button, we pass yourName to the function called GoThere.

The above is a very important example of how JavaScript handles events. Each and every part of a webpage can have events associated with it. Here we use a mouse click to launch a function that loads a new page. As we learn more about JavaScript, so we'll learn which events can be used for what. But for now, let's be content to explore the OnClick event that we've created.

2. Sending information to the next form

Let's have another look at the GoThere function:

That same old hidden function
  <script language='JavaScript'> 
    <!-- 
   function GoThere(yourname) 
        { 
        location="part2j.htm" + "#" + yourname.value; 
        } 
   //--> 
  </script> 

The first thing we note is that it's generally quite okay to hide JavaScript within the body of a html document, as we did on the first tutorial page. We won't do this much (mainly because we like everything upfront) - the only reason why we didn't put the above code into the header of the previous page, is that it would have confused you had you clicked on View Source as we invited you to do, near the start of that document!

What does the function do? Well, it's rather sneaky. It sets location to a new web page address .. part2j.htm .. and, Hey Presto! this page is loaded into the browser. But we do something even more sneaky - we take the name you typed in and add it to the web page address, preceded by a so-called "pound-sign" (#) - I usually call this # a 'hash' (although the name 'tictactoe' is really cute)!

In other words, the following fragment..

"part2j.htm" + "#" + yourname.value;

takes three little strings and joins them together (concatenates them). The name "part2j.htm" is joined up with a "#" character, and then with the string that you typed in, and was stored in yourname. Note how we say yourname.value - another one of these irritating little JavaScript rules - we passed the function the whole object, so we should refer to its value!

What does this #name mean? You know the answer already - it just tells the browser to go to a certain point in the web-page, with a name the same as the one you typed in! But wait a bit, that name can't possibly exist in the web-page we referenced, can it? Hmm. Maybe not, but does the browser care? The short answer is "Not much" - you can see that we now have a really rather cute way of passing information from page to page. Just send the information after the web-page name, preceded by a #.

We're two thirds of the way through our explanation. Now all we need to know is how on earth the web-page receiving the information makes use of it, printing your name at the top of the page. Here goes..

3. Using information in the next form

We know that the next form will receive the information after the 'hash' (#), but how can we make use of it? First, we need to know that:

JavaScript in the header of a web-page is always
processed before the page is written to the screen!

This means that if we have a function that can dynamically write to the web-page, this dynamically written part of the web page will appear on our screen before the rest of the page. What is this wonderful function that dynamically writes to a web-page? It's called:

document.write()

Anything in parenthesis is written into the web page. For example, the code that greeted you at the top of the current page was generated more or less as follows:

Dynamically writing to the page
 <script language='JavaScript'> 
 <!-- 
 yourname = window.location.hash.substring(1);   //pull out the name 
   document.write("<div align='center'><h1>");   //write header 
   document.write("Hello " + yourname);          //write greeting 
   document.write("</h1></div><hr>");            //finish off 
   }; 
 //--> 

Let's work through this line by line. The first line tells us that we can pull the information we sent out of the web-page address. It's stored in part of the window.location object, and the name of that part is, surprisingly enough, 'hash'! Note that this includes the leading '#', so we clip this off using the function substring(1), which gives us the contents of hash starting at the second character (remember that in JavaScript, we start counting at zero)! See how we got away with not saying var yourname .., as JavaScript is fairly tolerant and allows us to just make new variables on the fly without explicitly declaring them.

The second line uses our wonderful function write to write to the document. So do the third and fourth lines. What do they write? Look carefully. First they write a

<div align='center' >

followed by a <h1> heading.

The string that is being passed to document.write is in "double quotes", so when we use the align='center' instruction, we encase the word 'center' in single quotes. This prevents the confusion that we would cause if we here used double quotes again, and is really necessary.

Next, we write "Hello ", followed by the name we so carefully extracted from the location.hash. Finally we close off everything, and for good measure, include a horizontal rule <hr>

What's wrong with the above?

Well that should work, shouldn't it?

Whenever you've written some really cute code, it's a good idea to sit back, take a deep breath, and then ask "Well what can go wrong?". There are in fact at least three things wrong with the above code, cute as it is. Yes, it will generally work, but it needs to be dressed up a little. Here are the problems..

Problem 1. Spaces in Microsoft

Our old friend MS again! (Hmm, perhaps they've got something here). If you were to try the above code as is with Internet Explorer, and were to type in your name as (say) Joe Bloggs then you would notice something interesting. The message at the top of the screen would read:

Hello Joe%20Bloggs

Try this if you don't believe me! What's the problem? Well, IE doesn't like sending certain characters as part of a hash name. One of these is the space. So IE kindly translates the character into what it regards as a useful rendition of that character. It does so by (1) putting in a percentage sign and (2) giving the two-digit hexadecimal code for that character, which, in the case of 'space', just happens to be 20.

How do we fix the problem?
It's actually fairly easy to replace the %20's with spaces. Here's the code that will do it..

Getting rid of "%20s"
 <script language='JavaScript'> 
 <!-- 
 yourname = window.location.hash.substring(1);      //pull out the name 
 posn = yourname.indexOf("%20");                    //find the first %20 
 while (posn > -1)                                  //while there is a %20 
     { yourname = yourname.substring(0,posn) + " " + yourname.substring(posn+3); 
       posn = yourname.indexOf("%20");              //find next %20 
     }; 
     // here fill in rest of code 
 //--> 

How does this work? We already understand how we pull out yourname. The function indexOf just tells us whether the string "%20" exists inside yourname. If it doesn't, the value returned will be -1, but if it does, then the number returned (and stored in posn) will be the position in yourname of the first "%20", counting as always from the left and starting at zero.

We then use this value posn to snip up the string, and replace the "%20" with a space. Note how the new command while allows us to do this again and again until no more "%20"s are found! And that's it!

Before we rush off and implement this code, however, let's look at our other problems.

Problem 2. Netscape names

Netscape is far from immune from problems. Remember we said above (in answer to the question "Does the browser care if the #name doesn't exist?"), "Not much". Well, it turns out that if Microsoft IE doesn't find a #name in a page, it nevertheless still loads the page, and displays the page, starting at the beginning. Netscape Navigator is similar, but because it hasn't found the #name, it goes to the end of the page, as if to say "Look here, I'm at the end of the bloody page and I still haven't found the darn thing!".

Fortunately, there's an easy fix to this one. Simply insert the line:

Dynamically making a name for yourself!

    document.write("<a name='" + yourname + "'>");

The above code assumes that you've already acquired yourname as before. Is this the end of our troubles? No, not really. For it turns out that Netscape doesn't like names with spaces in them. So if we submit a name that contains spaces, then Netscape (although it doesn't translate them into %20's) won't see this string as a name, and so will churlishly go to the end of the document again.

What's the solution? Well, we're now having trouble with spaces from both IE and Netscape. There are a million solutions, but the snippet of code we would use is as follows (We insert it into our original GoThere function, killing the problem at the source)..

A good fix for spaces
 whoyou = yourname.value; 
 posn = whoyou.indexOf(" "); 
 while ( posn > -1) 
     { whoyou = whoyou.substring(0,posn) + "_" + whoyou.substring(1+posn); 
       posn = whoyou.indexOf(" "); 
     }; 

You can see that the above code is very similar to that we proposed as a fix for "%20"s. What it does is replace all spaces with _underscores_! Once we've done this, the Netscape problem disappears (underscores are fine within a name), and IE no longer translates our spaces into %20s, either. Of course, for the sake of prettiness, we should perhaps translate the underscores back to spaces, but that task is well within our means.

Problem 3. Other strange characters

There are other characters apart from blanks that cause problems. These include the slash character (Netscape thinks that everything before the slash is part of some complex path), and the colon. In addition, Netscape has problems with path names that contain characters such as quotes, and does the old "let's go to the end of the page and sulk" routine when it encounters these characters.

Fortunately, handling all of these problems is well within our new-found capacity. An idea! Why don't we make a function like this:

A general-purpose function to replace things!
 function Replace ( target, todo, withwhat) 
  { var fixme = target;                // load string to alter (into fixme) 
    var atpos = fixme.indexOf(todo);   // find position of string to replace 
    while ( atpos > -1)                // while still to replace.. 
      { fixme = fixme.substring(0,atpos)  
                + withwhat 
                + fixme.substring(todo.length + atpos); //replace 
        atpos = fixme.indexOf(todo);     // find next position (if exists) 
      };                                // .. end while 
    return fixme;                       // return altered string 
  } 

How does this work? We pass three arguments to the function: target, todo and withwhat. The function then looks for todo inside the string target, and replaces it with the string withwhat, doing so repeatedly until finished, at which point it returns the altered value using return fixme. (You can work it out .. fixme and atpos are just temporary variables). We might 'invoke' this function as follows:

Fixing the data typed in (and then using it)
   function GoThere(yourname) 
        { 
        whoyou = yourname.value; 
        whoyou = Replace(whoyou, ":", "_");     // replace colon, 
        whoyou = Replace(whoyou, "/", "_");     // and slash      
        whoyou = Replace(whoyou, " ", "_");     // and spaces. 
        whoyou = Replace(whoyou, "'", "");      //clip out single quotes 
        location="part2.htm" + "#" + whoyou; 
        } 

Final thoughts (before we move onto maths)

We've cheated a bit. We've used a rather artificial method of passing information between web-pages. In so doing, we've created a few problems, but in solving these problems, we've learnt quite a lot about JavaScript (and its limitations). Here's what we've learnt:

  1. Forms don't have to be used as they were intended. Their buttons and boxes can be hijacked for other purposes.
  2. JavaScript recognizes events. For example, we can use OnClick to respond to clicking on an item, and "hook in" a function that we have defined to handle the click event.
  3. We can include JavaScript within the body of html code (although we'll rarely want to do so).
  4. Using trickery, we can pass information between HTML forms (without having to use anything fancy like a CGI script).
  5. We can concatenate (join together) strings by simply using a + sign.
  6. We can dynamically write almost anything into a html document before it appears on the screen of our browser. We use the wonderful function document.write().
  7. window.location.hash gives us everything in the address of the current document after the "#" sign (including the "#").
  8. The function substring can be used to cut up a string. If we just provide it with one number (in parenthesis) then it cuts starting from that position, and moves right to the end. If we give it a second number, then substring cuts up to that second number.
  9. Remember that we always start counting characters with character number zero.
  10. We can create variables 'on the fly' by simply using their names - we don't have to use the var instruction.
  11. If you want to use quote marks within other quote marks, use (for example) double quotes on the outside, and single quotes on the inside. This is useful with document.write

In addition, we lied to you. Well, perhaps that's a bit strong. We concealed the truth. For (as you might have guessed) we couldn't resist the temptation to use our previous IE3 detecting code, and so we actually passed control from our first page to an intermediate page (called part2.htm) which traps IE3. You can visit this page by clicking here.

Note how on the first page, we had a little cop-out below our fancy "Visit the next page" button - to at least allow non-JavaScript enabled browsers to visit our explanatory page.

Note that our page construction is a teaching exercise - you shouldn't do this sort of thing in a 'real' web-page without extensive modification! For example, if yo use our #information trick, then perhaps it would be a good idea to take a tip from Microsoft, and translate unwanted characters to their hex codes, preceded by a % (Later we'll encounter two functions - escape and unescape that you can use to do the translation for you)! And use tricks like hijacking reset buttons sparingly, if at all! (There's a better way of making a button that we'll explore when we make our JavaScript calculator at the end of this page). By the way, can you think of any other potential problems with the way we've done things above? (Heh)!


Creating and using variables

If you've diligently read both the preceding page and this page, then you know there are two ways you can create variables in JavaScript:
  1. You can use the var keyword; or
  2. You can merely use a new name, and JavaScript automagically creates a variable to fit.

For example, you can define a variable thus:

var my_version = parseInt(navigator.appVersion);

(where have we seen this before?), or you can simply say something like:

yourname = window.location.hash.substring(1);

where we've never used the variable yourname before, yet JavaScript somehow decides that (a) this is indeed a variable, and (b) it must assign it the value provided.

Hmm, think about this. Firstly, why should there be two ways of creating variables, and secondly what are the consequences of wildly creating variables just by using their names?

Another ugliness in JavaScript. The answer to our first question is that there are two different classes of variables, called global and local variables. Generally you should always use local variables - these are the ones you were first introduced to, the ones you created by using the word var. Local variables are just that - they only have meaning 'locally' - for example, in the function in which they were defined. This is a good thing! Occasionally you might want to have a variable that can be seen anywhere and everywhere. Then you would use a global variable, which you create by simply using its name! (It is a complete mystery to us why the makers of JavaScript didn't have some formal way of defining a global by, for example, using a keyword like global, or something!) We should also possibly say something about variable names..

Variable names

How do we name a variable? Here are the rules:
  • Case is IMPORTANT. The variable Important is different from the variable important. Be warneD, i mean, warned!
  • Variables names must begin with a letter (or an _underscore);
  • Variables names can contain digits (0..9) but cannot begin with them.
  • Variables names can contain _underscores_;
  • Variables names cannot contain any other characters.

And that's pretty much it!

Later on we'll talk about the values contained in variables, and the different types of variables.


C what I can do!

The following sections are rather heavy - rush through them, and then come back when you get stuck, rather than painstakingly trudging through every syllable! JavaScript has many features in common with the language C. Apart from the common operators you would expect:

OperatorMeaning
+ addition
* multiplication
/ quotient (division)
- subtraction, and unary minus

(By the way, unary minus takes a single argument and changes the sign, for example - fred gives the negative of the number contained in the variable fred)

Where were we? Aha, we also have the following very C-like operators:

OperatorMeaning
% modulo (take the remainder of a division operation)
++ add one to the given number
-- subtract one from a number
&& logical AND - we've already encountered this in the context of if statements, as well as:
|| logical OR, and also
! logical NOT. In addition we have..
!= NOT equal to (We've also encountered this one)
= = EQUAL to (a common error is to only write one equals sign)
< less than (surprise, surprise!)
> greater than
<= less than OR equal to
>= greater than OR equal to

Don't be intimidated by these. Use will make them familiar - you'll find that these are often very powerful operators. Not, of course, as powerful as say, regular expressions in Perl, but powerful nevertheless. Intermittently even more convenient than the above are the following:

OperatorMeaning
= set something (on the left) equal to something else (on the right)
+= add the something on the left to that on the right, and put the result into the something on the left.
-= similar to +=, but subtract the thing on the right from that on the left.
*= multiply, similar to +=
/= divide the item on the left by that on the right, similar to +=
%= likewise, modulo

In addition, there are a host of bitwise operators, that act on a number bit-by-bit. We won't explore these here - see our 'Binary, schminary' section below.

Note the difference between = and = =
The first allocates a value, the second tests for equality of two numbers. A common error in C, Java and JavaScript is to write = when you mean = = (Most implementations of the languages will warn you, but the consequences can occasionally be devastating).

You write == as two equals signs one-after-the-other; we left a tiny gap in between them in our text above as otherwise some fonts have the two equals signs running into one another, which is really confusing!


Bodmas and friends

It won't surprise you to learn that, in common with languages such as C, C++ and Java, JavaScript understands ordinary old infix notation where we say things such as:

a + b * c

and this is translated as

a + (b * c)

In other words, the rules of precedence are those you would expect - Brackets come before division and multiplication, which in turn take precedence over addition and subtraction. (In junior school you possibly learnt about this rule as 'Bodmas')! Here are the (slightly more formal) rules of precedence for JavaScript:

Level (1 takes precedence over 2, and so on..) Operators on this level
1 ( ) also function calls and array subscripts (see below)
2 !   ++   --   - (unary minus; also ~, which you don't yet know about)
3 *   /   %
4 +   -
5 <<   >>   >>> (used to shift numbers bit-by-bit)
6 <     >     <=     >=     (you learnt these with if statements)
7 = =     !=
8  &   (What does this do?)
9  ^    (and this?)
10  |      (and this? - See later!)
11 && (back to our if statements again)
12  ||   (and again)
13  ?:  (What on earth can this mean?)
14 = += -= *= /= (and many more in a similar vein)
(Based on Mastering Javascript, J Jaworski, SYBEX, 1997 p 87).

You can see that things rapidly become 'non-trivial' and confusing. Don't worry about all the strange <=>!@#&$%^ stuff! We'll gradually introduce you to the important things as we work through our tutorial. For the time being, just remember that operators on the same level have no precedence over one another! For example, * and / are on the same level, so expressions containing both are simply 'parsed' from left to right. We suggest that where there is possible ambiguity you:

Use parentheses liberally .. they generally make things crystal clear. (But not nearly as clear as our favourite, Polish notation, which most programming languages understand about as well as they understand Polish. Go learn Lisp)!


Typing (no, not QWERTY)!

Think about it - there are different data types. You have, for example, integers, strings (we know what strings are from the first part of this tutorial), but what about logical values (true or false, as tested for by an if statement), and even floating point numbers? How does JavaScript distinguish between these various types? Well, to tell the truth, it more-or-less doesn't!

JavaScript is a weakly typed language. This means that the variable fred (for example) can, at different times, contain a number, a string, a Boolean value (true/false) or even a floating-point number. It can even become an object! Which, incidentally, is an almost complete list of the different data types in JavaScript. Here they are, in a list:

Data TypeExample(s)
String "This is a string, isn't it?"
Integer 123, -12345679, 0xff
Boolean true, false
Floating-point number 12.345, -3.1415926E-2
Object (As hinted at previously, and described later!)
Array (See below)

( The example 0xff simply refers to a hexadecimal number. Don't worry about this for now, and never worry about octal, which can also be represented in JavaScript, but is obsolete)!

This approach of being able to change the type of content in a variable on-the-fly may seem sexy, but it carries with it a host of problems. One of the most irritating is the following:

  1. What does "ABC" + "silly" give you? (Answer: the string "ABCsilly")

  2. What does 3 + 5 give you? (Answer: 8)

  3. OKay, how about 3 + "5" (Quickly now, what's the answer?)

Point made. JavaScript will automatically coerce a variable of a particular type into an appropriate one. This seems fine, but where something has an ambivalent value ("5" is both a string, and a number) unexpectedly horrible things can happen. In yet other circumstances, where there is no "correct" answer, an error may result.

The 'rules' state that strings are (generally) favoured over other data types, so, if you want to work out what 3 + "5" is, then the answer is "35" and not eight, as you might expect! (Next after strings come floating point, then integers, and finally logical operators). So numbers are converted to strings, and logical values to 0 or 1 (for false or true).

It is thus important to be able to explicitly convert between types (to be able to force such conversions). How do we do this? We use conversion functions. Here they are:

FunctionWhat it does
eval() Converts a string to a number (An error results if the conversion fails)
parseInt() Converts a string to an integer (As long as the string starts with an integer, even if other rubbish follows the integer. We've encountered parseInt before)!
parseFloat() Similar to parseInt, but extracts a floating point number.

Earlier documentation says that if parseInt doesn't find a number at the start of the string, it returns zero. In fact on more recent browsers, both parseInt and parseFloat return "NaN" (which stands for "Not a Number") if they don't find what they're looking for.

Even more confusing than NaNs are nulls and null strings:

Null strings and null

Let's start with a null string. Here's a null string:

""

Simply two quotes, with nothing in between. You might thing that such a peculiar animal has no use whatsoever, but we've already used a null string above, extracted for your pleasure here:


  whoyou = Replace(whoyou, "'", "");      //clip out single quotes

in our final incarnation of the GoThere function we defined. We replace a single quote with - yes - the null string (that is, nothing).

null is a very special (and confusing) thing. If I say something like:


  alert("The value of fred is " + fred);

.. and I haven't yet allocated a value to fred, then an error will result. Depending on how your browser is set up, you'll either get a mildly confusing error message, or the browser will simply stop interpreting the JavaScript!

The correct solution is to prevent this sort of error by checking your script carefully. Okay, occasionally you might need a distinct value (different from all others) that you can initialise a variable to, but the JavaScript value of null which acts as this sort of 'place-filler' to prevent an error, is likely to be more of a problem than it's worth. I would avoid it. An example of how null might mess you around is provided when we look at automatic type conversions - null is converted to "null" for string operations, false for logical operations, and 0 for numerical operations!

Escaping confusion

There are a few more things you need to know about strings. When Bill Gates cobbled together DOS, he chose to use the \backslash character to describe the path to a file (unlike Unix, which uses a /slash). In JavaScript (as in C and C++) we have a very different use for the backslash character - we use it as an escape. What do we mean by this? Well, certain characters (such as a "quote") will cause confusion if used in a string. We've already found one way to get around this - use single quotes, for example in:


   document.write("<div align='center'><h1>"); //write header 

Another is to escape the character. We could have rendered the above as:


   document.write("<div align=\"center\"><h1>"); //write header

You choose the method you want. For certain characters, an escape is extremely useful. Here are a few more characters - you need only remember the first:

Escaped characterMeaning
\n New line (line feed) i.e. "move to next line". Most useful!
\b Backspace - of little use
\t Horizontal tab - you may occasionally find this of use
\r Carriage return (of little use)
\f Form feed (You'll probably never use it in JavaScript)!

Much later on we'll encounter another quite different 'escape' - there's actually a function called escape() which does what Microsoft did above - turns all the funny characters in a string into percentage signs. There's even an unescape() which turns things back again. At several points we'll find that, with the whole English language to choose from, our JavaScript developers had such an impoverished vocabulary that they had to use the same word for somewhat different concepts!


Binary, schminary (with a touch of Logic)

This section does assume that you (more-or-less) understand hexadecimal arithmetic (You have no excuse, as we explained it in our html tutorial). Here we delve into binary (base two) arithmetic.

Briefly Binary
If you know Hex, binary is a cinch. In binary, we only have two possible digits 0 and 1, just as in decimal we have ten (0..9) and in hex we have sixteen (0..F). So we count as follows:

0

1

10

11

100

.. and so on. The interesting thing is the relationship between binary and hex. Consider, for example, the decimal number 10010. What is this in

  1. hexadecimal, and
  2. binary?
Well, we know that decimal 16 times 6 is 96, so the hex representation of 10010 is 6*1016 + 4, in other words 6416. What is this in binary? Well you can laboriously work through, dividing 100 by various powers of two, but I'll tell you at a glance that the answer is 0110 01002. How do I know this? Well, there is a direct correspondence between each hexadecimal digit and four binary digits - this makes sense, because 24 is sixteen! So we take our 6416, break it into 6 and 4, and convert these to binary to get 0110 0100.

As long as you can count to 1111 in binary, you can convert between hex and binary with consummate ease!

On the previous page we explored the if { } else { }; statement. We therefore know a little about Boolean logic - how statements can be either true or false, and how we can combine such 'truths and falsehoods' using the || and && operators, as well as the ! operator which turns things around (false becomes true, true becomes false).

What we have not yet told you is that similar logic can be applied to numbers .. we can for example take the number 3 (binary 11) and perform an AND operation on it with, say, the number 1 (binary 01). We could say something like:

   var fred = 3; 
   var jane = 1; 
   var robin = fred & jane; //logical AND of the two numbers 
   alert ("The answer is " + robin); 

What is the answer, and what does it mean? When we AND two numbers together, what is done is that corresponding bits are ANDed together. A "1" is regarded as being true, and a "0" as being false. The usual Boolean rules apply, so 1 & 1 gives 1, all other possibilities give zero. Anding 3 (Boolean "11") bit-by-bit with 1 (Boolean "01") gives us "01", as you would expect.

Similarly | is used to OR together two numbers. For example, (hexadecimal)
0x13 | 0xC gives us 0x1F. Can you see why? (Ox13 is 0001 0011 in binary, 0xC is 0000 1100, so if we OR these numbers bit-by-bit, we get 0001 1111, which is the same as 0x1F).

There is one other Boolean operator you occasionally might come across. It's called XOR (or 'exclusive or'). In a similar way to A AND B (which means BOTH A AND B), A XOR B translates as "this is true only if either A is true or B is true, but not both". It's like one of those passages with a light switch at both ends - if both switches are off, the light is OFF. At one end of the passage you flip the switch on and - Presto! - the light goes on. You then go to the other end and flip that switch into the 'ON' position and what happens? The light goes OFF again!

An example of XOR on two hexadecimal numbers:
0x12 ^ 0x11 gives you 3 (Try converting to binary and performing an exclusive OR, bit-by-bit).

As if this weren't enough, JavaScript allows you to perform other bit-orientated operations on numbers. For example, you can shift every bit in a number ONE BIT LEFT, so that binary 0111 would become binary 01110. There are two operations to shift things right (can you think why this might be?) Here is a summary of bit-related JavaScript operations:

OperationMeaning
& AND (bit-by-bit)
| OR
^ XOR (exclusive OR)
<< left shift (same as multiplying by two)
>> right shift ('propagates sign' i.e. preserves negative numbers)
>>> logical right shift (messes up negative numbers, has other uses)!
&= Similar to += (above) but performs logical AND
|= Logical OR as for &=
^= Logical XOR, as for &=
>>= also <<= and >>>= Shift operations, as for &=

The reason why we have two right shift operators is related to the peculiar (but logical) way that computers store numbers. Negative numbers are generally stored in two's complement notation. (The way this works is that, taking the binary value of the number, we change all zeroes to ones and vice versa, and then add one). It turns out that when we store negative numbers in two's complement notation, the leftmost (highest) bit of the number is always a one, and with positive numbers, this bit is zero .. we therefore call this the sign bit. You can see that right shifting such a number and not preserving the sign bit will muck things up rather. But, in a manner vaguely reminiscent of the Y2K problem, one can also store a larger positive number in the same space if we just ignore 2's complement. Here it makes no sense whatsoever to preserve the leftmost bit (it isn't a sign bit), so we have two different shifts. Chaos rules!


Arrays

An array is simply a grouping of similar objects. In fact, because of the weak typing of JavaScript (and one other reason), it's possible to store dissimilar items in the same array! But we're getting ahead of ourselves. First let's say how we make and use arrays. We create an array Brad with say five elements by saying:

Brad = new Array(5);

We don't have to know beforehand how many elements there are in the array. We could have just said Brad = new Array(), and then created elements on-the-fly, as we will shortly learn. What's the difference? Well, if we specify the number of elements, then each element starts off with the offensive, nasty little value null, which we discussed above. Watch out for this, especially as some versions of JavaScript will return "undefined" rather than "null" as the value of these elements.

Okay, how do we put something into an array? Easy:

Brad[0] = "Any old string";

See how we use [ square brackets ] to refer to an element of Brad. This gives you a hint of how you pull something out of an array:

var Janet = Brad[0];

will extract the value we put into Brad[0] and copy it into a variable called Janet. Note how the first element of an array has the index 0 - remember than in JavaScript, we count starting at zero! If the element you refer to doesn't exist, don't worry - JavaScript will create not only that element, but all the undefined elements 'lower than' it!

There are still more tricks up our sleeves. We will next look at "pre-defined" arrays (otherwise known as "Dense Arrays"), and then at multi-dimensional arrays.

Dense Arrays

Assume you know the elements that will occupy an array. It makes sense to be able to 'set them all up' in one fell swoop, thus:

Dwarfs = new Array ("Happy", "Sleepy", "Dopey", "Sneezy", "Oin", "Gloin", "Frodo", "Glod");

Multidimensional Arrays

There is no rule that forbids an array from having as one of its components, another array. This is rather clumsy, but a shorthand even exists for accessing elements of this 'sub-array'. Let's look at an example:

square = new Array (  
    new Array(1,2,3,4), 
    new Array(1,4,9,16), 
    new Array(1,8,27,64), 
    new Array(1,16,81,256) ); 
alert ("element row 3, column 2 = " +  square [3] [2]);

Here we create an array called square, with each element a separate array. The shorthand way of accessing each element is to refer to the element of the main array in the first square brackets and then the sub-array as the second. So square[3][2] gives us 81. (The real reason why JavaScript arrays can contain a variety of different data types is that they are actually Objects. For a detailed consideration of objects, see the third page of our tutorial).


Trig and stuff!

It's not that surprising that JavaScript has built into it a variety of mathematical functions. These include basic trigonometric functions, logarithms, and a few constants. Here they are:

FunctionMeaning
Math.sin The sin of an angle.
Math.cos Cosine.
Math.tan Tangent.
Math.asin, Math.acos, Math.atan Arc sin, cos and tan respectively. The inverse of sin, cos, tan. (There's also an atan2).
Math.random() This useful function doesn't actually generate a random number, but a pseudo-random one. Useful in games!
Math.abs() This simply gives the absolute value of a number (if it's negative, turns it into a positive number of equal magnitude).
Math.log() and Math.exp() You would not expect that log refers to the natural logarithm of a number (base e). Unfortunately, in JavaScript, this is the case! The inverse function is what one would expect - exp. There is also a power function, pow that raises a number to a given power.
Math.round(), Math.floor(), Math.ceiling() These are all used to gently adulterate floating point numbers. round() returns the closest integer to a number (what about 1.5 ?), floor() returns returns the greatest integer <= to the given number, ceiling() the smallest integer >= the number.
Math.min() and Math.max() Both of these functions compare two numbers, returning either the lesser (min) or greater (max) of the two.

Note how each and every one of these functions must be preceded by Math. - otherwise you'll get a confusing error message (or JavaScript will stop being interpreted). This is also true for constants:

ConstantMeaning
Math.E Well, actually it should be e. But you know what we mean - it's about 2.71828182. The basis of natural logarithms..
Math.PI Yep, good old-fashioned pi. About 3.1415926535. A good approximation is 355/113, but here we have a convenient and more accurate one.
Math.SQRT2 The square root of two, if you need it.
Math.SQRT1_2 Hmm. The square root of one half.
Math.LN2 The natural log of 2.
Math.LN10 The natural log of ten.
Math.LOG2E The base 2 logarithm of e.
Math.LOG10E The base 10 log of e.

Putting it all together

We've incorporated much of what you've learnt into designing
a simple calculator. Alternatively, you can skip this and go on to our next lesson.


Webpage author jvs@anaesthetist.com Last update: 2000-10-7