In this article, we want to say a little about using JavaScript to write Web-based models that run in the user's browser, as an alternative to the familiar approach of running them on the Web server. We are also offering the source of our BBC Budget Day tax calculator, which this year we wrote in JavaScript. We hope it will be a useful demonstration of how to use the language.
Until this year, all our models Virtual Economy, the Virtual Learning Arcade simulations and the BBC Budget Day tax calculator ran on Web servers. This is great for ease of access. As we enthused in an article published back in 1995 when we were just starting off, anybody, no matter what machine or operating system they have, can interact with a server-side model as long as they have a suitable browser.
But the ease of access is counterbalanced by the problems that arise from concentrating all the processing on to one server problems which can become acute for frequently-run programs. This year, BBC statistics showed that our tax calculator was run 291,311 times on Budget Day. We had written it in JavaScript; but suppose that like the previous years' versions, it had run on the server. And suppose that each run took one second, a not unreasonable assumption. Then altogether, it would have occupied the server for one-third of a day one-third of its capacity. In fact, we do know that at one point during Budget Day 2001, our model was accounting for over 25% of the load on the server. To avoid such loading this year, we switched to JavaScript. JavaScript code is written into a Web page, sitting between the HTML tags. So like the rest of the page, it lives on the server. When you request a page, however, your browser downloads the lot and then executes the JavaScript itself, leaving the server nothing to do other than processing the initial request.
Not all models will be so heavily used. JavaScript, however, also offers benefits in increased responsiveness. For instance, errors in input can be caught immediately, without having to send the input to the server for checking. So what is JavaScript, and how do you run it? In a short article like this we can't provide a complete introduction to the language, but we shall give some pointers to the most important features, and some advice on how to program safely in it.
If you want to see our example, you can download the source from our Virtual Worlds site. Instructions on how to use it are included on the page. To run the program, go to this year's BBC version or our copy, linked from the Virtual Worlds page (see References).
With its curly brackets, 'if' statements and 'while' loops, JavaScript looks not unlike C and Java. The syntax is similar, the same arithmetic operators are available. If you know one of these languages, basic JavaScript is easy to pick up. Where JavaScript differs is in its handling of variables and objects, and of course in its ability to control a Web browser. As far as variables go, JavaScript is what's called 'dynamically typed'. Any kind of value can be assigned to any variable; you don't need to use a type-word such as int or String to tell the compiler what the variable contains, but just use the word var for all variables. This does make writing programs easier. However, it also means the compiler can't detect 'type-check errors': those accidents that happen when you pass, for example, an integer to a function that expected a string. Such errors will remain until runtime, and if not caught by careful testing, may lie undetected for days or weeks until suddenly exploding when the statement they're in finally gets exercised. So JavaScript is simpler than C and Java; but because of this, it needs much more care in testing and debugging. Like Java, JavaScript has objects, and you can play the same games with methods and inheritance that Java permits. But be warned! JavaScript's object system is quite different, based on something known as prototype-based inheritance. Java and C++ programmers will need to learn some new tricks to use this effectively. In learning about these, we found David Flanagan's JavaScript: The Definitive Guide (2001) very helpful, and we thoroughly recommend it to you.
On the positive side, the JavaScript object system makes it
very easy to create records for example, a structure
representing a book, with fields for author, title and ISBN,
or a pair representing a complex number, with real and
imaginary components. Arrays and lookup tables are also
straightforward. But again, there is little compile-time
checking. You might intend your book
record to have a
field called Author
, but the compiler won't tell you if you
accidentally write auth
instead.
There's a general point here. Look at any JavaScript newsgroup or list, and you'll see many postings from newcomers who, perhaps because it's often referred to as a 'scripting language', have gained the impression that JavaScript is simple, enabling you to write exciting programs after only a few hours of study. Not so. It is a complex language with unusual (but not inelegant) implementations of some common concepts, and little help to be gained from compiler error-detection. JavaScript programs need at least as much care as those of any other language. Divide your code into separate modules, one module to a file; test each separately; comment all variables and functions, making sure you know what kind of data each contains or gets passed; test functions in isolation before using them in the rest of your code.
From the point of view of this article, JavaScript's most important feature is its ability to control the Web browser. Let's consider our tax calculator. With the old server-side version, the user first pulled up a simple form into which they entered details such as marital status and house ownership. They then clicked 'Submit' to send this to the server. The server checked the data, decided what financial information it needed, and generated another form which it sent back as HTML. The process was then repeated, except that this time, the server was doing the tax calculations and returning them in the results page.
With JavaScript, all this takes place in your browser. Clicking 'Submit' on the first form invokes a stringprocessing function which extracts your data from the form's input fields and then performs a series of string concatenations to put together a string containing the text of the second form. That's right code running in the browser is generating a complete new Web page which can then replace the one currently on display.
So the second form then gets displayed. With this form, there is an issue of data validation because if you type, for example, a letter where a number is expected, we have to make sure it doesn't get into the model and crash it. (The old server-side input form side-stepped this problem by using menus.) We do two kinds of validation. It's possible to check some things as soon as the user types a character: letters never make any sense in a numeric field, and neither do most other non-digit characters, so we can reject those straight away. However, some checks have to be left until the form is finally submitted. For example, blank fields aren't valid. But we can only reject a field if it's blank at the time the form is submitted, not if it becomes blank while the user is typing: in the latter case, the user might just be in the process of retyping a number.
After the second form has been submitted and validated, our program extracts its fields, packs them into a single structure (which is more convenient to pass around than lots of separate variables), and passes it to the tax routines. These use arrays to store tax bands and rates, and records to store the tax systems, and make plentiful use of JavaScript's arithmetic operators: there's not much to say, except to convince you that you really can run a tax model in your browser.
Finally, the tax calculator having done its work, another group of string-processing functions takes over and generates the output page, embedding the results into it as tables. As with the second form, this is stored as a string containing HTML; and as with the second form, we use JavaScript's built-in browser-control features to make it switch over to displaying this string as a new page.
That then is a brief example of some of the things JavaScript can do. The code is here we hope it will be useful.
The obvious way is by loading it into the browser. Create
the file (or files) that is to be your final Web page, with your
JavaScript code and HTML in it; put it on to your website;
and then open it from the browser. If you don't have a Web
server, the browser will probably let you type the filename
into the address bar, preceded by the prefix file:
.
When you test code in a browser, be warned! Our
browsers were truly dreadful at reporting errors, frequently
just displaying a blank page if there was something awry
in the code. This is frustrating, but there is a way to trace
how far the browser has got. Sprinkle the page liberally
with calls to the alert
function. This displays a dialogue
box when called, and can be used for debugging in the
same way you'd use a print statement in other languages.
When developing complicated code, we favour a different
approach Rhino. This is an open-source Java
implementation of JavaScript, available from
http://www.mozilla.org/rhino/ . If you have Java, Rhino is
easy to install. The Rhino documentation tells you how to
invoke the interpreter; doing so will pop up a window
into which you can type JavaScript commands. These can
be simple arithmetic expressions Rhino makes a handy
desk calculator or calls to any JavaScript function that
Rhino knows about. You can load one of your own files
by calling its load
function, and once you've done this, all
the functions defined in it become available, so you can
test them by trying them out with various arguments. What
you can't do, since Rhino isn't embedded in a browser, is
to use those JavaScript functions that display and alter Web
pages. But any kind of Web-based model will contain a lot
of functions that have nothing at all to do with output
such as Ready Reckoner's tax calculations and we do
recommend getting these tested and working under Rhino
first, before starting with the others.
The main problem with JavaScript is compatibility. In the beginning, Microsoft and Netscape each went their own ways with the language; although the core functions and commands were generally the same, there were big differences in some of the browser-interaction features. As new versions of the browsers appeared, new features were implemented, leading to incompatibilities not only between manufacturers but also between different releases of the same manufacturer's browser. The situation seems now to be slowly improving: older browsers are dropping out of use, and we seem to be seeing some de facto standardisation. The topic is complicated, but it can be handled once again, we refer you to David Flanagan's excellent book. We have found useful a brief account of the history of JavaScript at http://www.howtocreate.co.uk/jshistory.html , and a detailed breakdown of which browsers implement which features at http://www.xs4all.nl/~ppk/js/ .
As well as intentional differences in implementation, browsers also suffer from bugs, which can cause a lot of grief until you realise what's going on. The most comprehensive site we have found for this is a German one, and for those who can read German, we give the URL: it's at http://www.browser-bugs.de/ .
Don't be discouraged by this section: with the aid of the references cited, a skilled programmer can solve these problems easily. JavaScript gives you scope to do many interesting things enjoy it!
The URLs here were checked on 20 June 2003.
Flanagan, D. (2001) JavaScript: The Definitive Guide, O'Reilly.
Kobert, T., Seeboerger-Weichselbaum, M. and Spona, H., 'Browser bugs' (in German), http://www.browser-bugs.de/ .
Koch, P-P., 'JavaScript tricks, tutorials, and compatibility', http://www.xs4all.nl/~ppk/js/ .
Paine, J. and Stark, G., 'BBC Budget tax calculator', http://www.virtual-worlds.biz/rr_source/ .
Wilton-Jones, M., 'A history of JavaScript', http://www.howtocreate.co.uk/jshistory.html .
Rhino JavaScript implementation. http://www.mozilla.org/rhino/ .
Graham Stark
Jocelyn Paine
Virtual Worlds
136 Hainault Avenue
Giffard Park
Milton Keynes, MK14 5PG
UK
Tel: (+044) 01908 618239
Email: graham.stark@virtual-worlds.biz
popx@virtual-worlds.biz