God got His creation perfect on the first cut; the rest of us get
to debug our work. I think in my entire life I might have gotten two programs
right the first try, both of them very short (one-liners don't count).
Most of your time programming will be spent trying to figure out why it
didn't work right -- or often not at all. This page is explains some useful
ideas for fixing JavaScript. Other programming languages and development
environments have their own ways of dealing with bugs.
The grown-up languages like C++ and Java have two important debugging tools not available to JavaScript programmers. One of these is the compiler, which stops with an error message when it encounters something it doesn't understand. The error message often is completely unrelated to the actual error, but at least it tells you (more or less) where the problem is. Most compilers keep going and produce additional error messages for subsequent lines, which are even more bizarre and very voluminous, because the compiler tends to become hopelessly confused after the first error. Experienced programmers just fix the first error and try again.
JavaScript has something like a compiler, which converts the script into runtime code slightly more efficient than the text stored in a web page, and that compiler does stop when it gets confused, but error messages make no sense to the average user because it is usually executing on a client computer far far away from the programmer who wrote the code. On my browser the interpreter just gives up and displays nothing when that happens; in Windows you can tell it to enable script debugging, but then it asks you for a debugging tool that knows how to do it -- all of which cost money. Your only hope in such cases is what I call "lion hunting."
The other debugging tool available to C++ and Java lets those programmers
step through their program one line at a time. If your browser is FireFox,
then you can download FireBug,
which lets you do much of the same stuff for JavaScript. It's "open source"
which means it's incredibly closed-mind (very hard to figure out, and totally
inadequate documentation, but if you persevere, you can make it work for
you). If you already paid for Microsoft Office, it has a similar debugging
tool, described
here. My free alternative, which works in every language, is called
"logging".
Unfortunately, you can't always just slice the program in half at line 16. If you have a block with its opening brace before the divider and its closing brace after the divider, cutting it there just introduces a new bug in each half. So you need to be more clever.
One way to divide a program is to replace the body of a function with a pair of empty braces {}. If the program now tries to run, then the bug must be inside the function. Alternatively, you can leave the functions complete, but remove the code that calls them, but if you left out a brace or parenthesis, your only hope is to cut out code.
An easy way to remove code without losing it is to "comment it out"
by adding the double slant // in front of each line. Later, after
you identify and fix the error, you can just delete the double slant on
each line. If you look in my JavaScript interpreter,
you will see numerous lines of code commented out. I put them for debugging,
then when it was working, I left them there but commented out.
If you have a simple need, you can use window.alert("some text")
as a one-line log. Later, when we get into animated
games, you can look at the source code of my
Kickball example, where I used an alert to track why my KickMe
function was not working properly (it's now commented out).
But I knew the problem was in the function or the loop where it was called. I changed the loop condition to false (so it wouldn't run at all), then stubbed out the function to {} but still nothing. I commented out everything inside the loop. Still nothing. Since its call was now only a comment, I removed the function entirely, and it ran. Now I knew that the problem was the first line of the function, which looked like this:
function replacestring(new,start,len,old) {}Looking at this, I remembered "new" is a reserved word (used for creating new objects). I changed its spelling to "newly" and it worked. Slowly I put the rest of the code back in and finally changed the false back to true, and did not find any other bugs. I was lucky. You won't be. Maybe next year you will be lucky, if you work hard this year at learning to program.
abstract
boolean break byte case catch char class const continue debugger default delete do double |
else
enum export extends false final finally float for function goto if implements import in |
instanceof
int interface long native new null package private protected public return short static super |
switch
synchronized this throw throws transient true try typeof var void volatile while with |
Most of these names have meaning only in Sun's proprietary language
Java, which JavaScript was intended to resemble. Maybe they will eventually
come to mean the same things in JavaScript, but smart programmers won't
use them, because none of the older browsers will know about the new stuff.
If you want people to use and enjoy your programs, you need to make it
easy for them. Abusing your users does not make happy campers.
Unfortunately, JavaScript is in a permanent vegetative state when it comes to data input, so the only way to get the script in for a program to look at it is to make it part of that program's literal data. This is very clumsy and frought with additional errors that you don't need, so I also wrote a small WinXP program "JStest.exe" to add the necessary quotes. This entire tutorial with all incidental files can be downloaded as LearnJSinfo.zip; be sure to unpack it before trying to run things. The JStest.exe program is not very beautiful; it just puts up a file dialog so you can select an HTML document with your script in it. It extracts the script, adds the necessary quotes and escapes, then copies it to the clipboard, so you can paste the result into a copy of the "Jscript.html" page containing the interpreter.
Initially this page has the whole interpreter, plus a small demo script for test purposes, which starts out like this:
<html> <head> <title>JSinterp 10 Dec 22</title> </head> <body> <script>Using a text editor (like WordPad) you replace the nine lines starting with "var theScript = " (shown here in red) with whatever is in the clipboard after you run JStest.exe, then open the page in your browser. It will take a while to interpret your script, but if it finds errors, they will be displayed on the page. If it gets to the end of your script without reporting any problems, then your original script will probably run in a browser -- if not, I need you to send me your script, so I can fix whatever went wrong.var theScript = ""
+ '\r function fact(n) {'
+ '\r if (n==0) return 1;'
+ '\r return fact(n-1)*n;}'
+ '\r document.write("3! = "+fact(3));'
+ '\r'
+ '\r var whom = 4;'
+ '\r document.write(" Hello "+(whom+3));'
+ "";var Logging = 2; // =0 is no log; =1 shows source function calls & returns
// =2 shows var ass'ts & some comments; =3 interp'd flow control (=4 includes if)
// =5 shows interpreter flow control (nonterminal entry/exit) & tokens
// =6 is full interp trace; =7 shows extra info; >7 logs in func defn & GeTok
var LogAtLine = 0; // >0 turns on Logging when it reaches that code line
var LogAfter = 0; // >0 turns on Logging after that many tokens
...
There is more on Using the JavaScript Debug Interpreter, which you might wish to become familiar with.
Next: A Bigger Example
Tom Pittman
Rev 2010 December 23