Interesting JavaScript Discoveries
Every language has its own idiosyncrasies -- ways that this
language behaves differently from expected. This is my own list of discoveries
that I made in the first few months of using JavaScript.
SYNTAX
It is almost amusing that JavaScript is so loose in many respects (variable
declaration, data types, function parameters, etc.) but so tight in other respects (case
sensitivity). The developer must simply learn where it is "tight" and be
sure to conform.
- JavaScript is generally forgiving about including zero, one or more spaces around
operators (e.g. x-1 vs x - 1 a==b vs. a == b)
- JavaScript is very specific about case:
- JavaScript keywords are generally lowercase: "if", "var",
"document", "write".
- JavaScript object names are mixed case: "Array", "Object",
"Date"
- JavaScript lets you name (and use) two methods or two variables that only differ by case
(e.g. calcRate and CalcRate can coexist and perform different purposes)
VARIABLES
Experienced developers will probably find the JavaScript's
"looseness" around variables to be its most shocking feature. Variables are discussed in more detail elsewhere however the some
points will be restated here:
- Declaration: Variables do not have to be declared before being used.
When they are declared, they are simply defined as "var" (for variable)
with no data type.
Data Type: A variable's data type is defined by the last
value assigned to it (so called "dynamic typing"). A variable could be a
number on one line, then assigned a string value and later be assigned an object
reference. JavaScript would just change its data type on-the-fly with each
assignment.
Initialization: Variables dont have default initialization and
JavaScript does not fail if you try to use a variable that is not defined. As a string,
its uninitialized value is "undefined". As a number, its uninitialized value is
"NaN" a special value meaning Not a Number.
Clearly, numbers and strings can be corrupted when combined with an uninitialized value.
Variable Access: Any variable that is not a function variable (i.e.
defined within a function) will be global (i.e. accessible anywhere).
Beware Automatic Conversion: With some exceptions (e.g.
some cases with early Netscape 4.x), JavaScript will attempt to convert variable types to
make them work. Consider the code extract:
var x = ""; // emtpy string
var y = 0; // the number zero
if(x == y) ...
JavaScript will attempt to synchronize their data types before the comparison takes place.
The result of "if(x==y)" would be true. Similarly, if I call the function
isNaN(x) (x defined as above), x will first be translated to zero and therefore deemed as
a valid numeric.
So how do you distinguish between empty string (x) and the number zero (y)? The typeof
function can help sort out the initial data type (before JavaScript attempts to translate
it). For example "typeof x" would evaluate to "string" while
"typeof y" would evaluate to "number".
JavaScript-Java Data Type Compatibility: JavaScript has
a looser definition of a number than Java. For example, the following are valid
JavaScript integers "+5" "2." " 8 " (return False to isNaN)
but all of these will fail a string-to-integer data conversion in Java. This would
be a problem if you are submitting HTML page elements to a JSP or Servlet. One
simple solution is to have JavaScript multiply the value by one before submission so the
extraneous characters (+, space, etc.) that bother Java are removed. Including the
following code in pre-submission logic will solve the problem:
if (!isNaN(document.formMain.txtNum.value)) { // valid number
document.formMain.txtNum.value = document.formMain.txtNum.value * 1;
} else {
// appropriate error (non-numeric in numeric field)
}
FUNCTIONS
- Parameters: JavaScript is "forgiving" about the number of
parameters that you pass a function. If you supply too few, it will assume that the later
(missing) parameter values are Null. If you supply too many, the function call will still
work and the extra parameters will be included (along with the defined parameters) in the
functions arguments property (an array).
- Overloading: Function overloading is supported only in the sense that
you can pass any number of parameters to a single function then you can use the arguments
property to deal with the actual number of parameters passed in. You cannot, however,
define the same function twice (e.g. once with one parameter and once with two parameters)
and expect JavaScript to select the instance with the appropriate function signature (as
Java or other more sophisticated languages do). If you define the same function twice,
JavaScript will use the function instance defined later in the script and ignore the
earlier definition.
- Parameter Passing by Value/Reference: Simple data values (e.g. string,
number, boolean) are passed by value into functions (so any updates to the parameter do
not persist after the function is complete). By contrast, objects (e.g. a form, a custom
object) are passed by reference (so updates to the parameter persists after the function
is complete). When the return value is used for other purposes, the cleanest way to cause
a data value to be returnable (i.e. have its value persist after the function is complete)
is to make that data value part of a custom object.
- Duplicated Name: If you accidentally give a form element name the same
name as a function name, you cannot call the function (e.g. calling a button
"hideList" will mean the hideList JavaScript function cannot be called).
STATEMENTS
IF
- Nothing is flagged, if you try to evaluate (a = b). b is
assigned to a and, if the b is non-zero, it evaluates to true. The same is try for while (a = b)
- outer brackets around the full "if expression" being evaluated are mandatory,
including when the whole result is negated. For example, the outer brackets are required
here: if (! (a==b))
- Navigator does not treat 1 = "1" (number 1 equal to string 1) but IE does
treat them as equal. Result: make sure data types are the same before comparing to ensure
Navigator compatibility.
SWITCH
- if the break is omitted at the end of a case clause, execution continues in the next
case statement (until a break or the end of the switch statement is reached).
OBJECT REFERENCES
- From a form element, this.form is generic code which provides a handle back to the
parent form.
FORM ELEMENTS
Selection List
- Selection list text and values are automatically converted to string
- Selection lists automatically size to the widest element. You therefore always have to
include some data (e.g. a prompt) in the first element, if there is any chance that the
list might be empty at anytime in the process. A selection list with zero elements shrinks
to a very narrow size (and looks bad).
- Navigator does not automatically refresh the size of a selection list (but IE does). For
Navigator, you must call history.go(0) to refresh the whole page and thus the selection
list size.
... back to JavaScript Topics
Copyright © 1997-2010, Woodger Computing Inc.