The Language of Javascript
Written on 06/29/12 at 14:07:18 EST by GentleGiant
JavascriptingThere are many, many different computer programming languages in use today. Each has its own set of special features, which are highly praised by its fans and vigorously panned by its detractors. If you have worked in more than one language then you are aware that there is a continuum of language styles, ranging from highly structured languages such as Ada to more free-wheeling ones such as Lisp. Many are associated with specific settings or applications. Ada, for example, is often found in military projects, while Lisp is often associated with artificial intelligence. Some languages, such as HTML, the language used to describe the layout of World Wide Web pages, have a well defined organizational structure, but have very little in the way of traditional program structure (there are no data types, for example).

In trying to understand a new language it is not only important to master its syntax, it is also vital to appreciate its style-the way in which that language can be used to accomplish specific goals.

Anyone who has programming in almost any modern declarative language, such as C, C++ or Pascal, will feel immediately at home. In addition, HTML authors who have never programmed will be able to rapidly acquire JavaScript proficiency.

JavaScript is based on an action oriented model of the World Wide Web. Elements of a Web page, such as a button or checkbox, may trigger actions or events. When one of these events occurs, a corresponding piece of JavaScript code, usually a JavaScript function, is executed. That function, in turn, is composed of various statements which perform calculations, examine or modify the contents of the Web page, or perform other tasks in order to respond in some way to that event. For example, pressing the SUBMIT button on an online order form might invoke a JavaScript function that validates the contents of that form to ensure that the user entered all the required information.

In general, the elements of a JavaScript program can be divided into five categories, as follows:

1 Variables and their values
2 Expressions, which manipulate those values
3 Control structures, which modify how statements are performed
4 Functions, which execute a block of statements
5 Objects and arrays, which are ways of grouping related pieces of data together

This set of categories is very similar to many other languages. JavaScript is somewhat minimalist in its approach. Many familiar elements, such as explicit data types (int, String, REAL), are missing or have been substantially simplified. However, JavaScript also provides a number of powerful object-oriented constructs which greatly simplify program organization. In this way JavaScript has the expressive power of languages such as C or Java, while also having fewer rules to remember.

Variables and Values
One of the main differences between JavaScript and most other languages is that it does not have explicit data types. There is no way to specify that a particular variable represents an integer, a string, or a floating-point (real) number. Any JavaScript variable can be any of these-in fact, the same variable can be interpreted differently in different contexts.

All JavaScript variables are declared using the keyword var. A variable may be initialized, meaning that it is given a value when it is declared, or it may be uninitialized. In addition, multiple variables can be declared on the same line by separating their names with commas. For example, the statements

var x = 7
var y,z = "19"
var lk = "lucky"
declare a variable named x with initial value 7, an uninitialized variable y and variables named z and lk whose initial values are "19" and "lucky", respectively. It might seem that x is an integer, z and lk are strings, and y is some undefined quantity. In fact, the real story is a little more complicated than this. The value of each variable depends on the context in which it is used. This context is related to the order in which the variables are seen. As you might guess, the expressions

5 + x
lk + z
evaluate to 12 and "lucky19", seemingly confirming our suspicions about what they really are. However, it is also possible to form the expressions

lk + x
x + z
which evaluates to "lucky7" and 26, respectively. In the first expression, x has been interpreted as a string, while in the second, z has been interpreted as an integer.

JavaScript often attempts to treat all variables within a statement as if they had the same type as the first variable in the statement.
These examples illustrate two critically important points about the JavaScript language. First, while JavaScript does not have explicit data types, it does have implicit data types. Second, JavaScript has a set of conversion rules that allow it to decide how to treat a value based on the context in which it is used. The context is establish by reading the expression from left to right. In the expression x + z, for example, x is implicitly a numerical value, so that JavaScript also attempts to view z as a number and perform the sum numerically. It succeeds, and the expected 26 results.

What would have happened if we had tried x + lk? The x variable occurs first on the left, and is really a number at heart. JavaScript thus tries to interpret the variable lk as a number, too. This is extremely unlucky, in fact, because "lucky" cannot be converted to a number (while z, the string "19" could). JavaScript reports an error if asked to evaluate x + lk. To understand JavaScript variables and values, therefore, it is necessary to understand its set of implicit types and how they may be converted to one another.

Before we enter into these details, let us consider one final example. In all the preceding cases, the uninitialized variable y was never used. What would be the value of an expression such as

x = z + y
Of course, as in all other programming languages, the result of using an uninitialized variable is never good. Since y has never been given a value, there is no way this expression can be evaluated. It may result in something seemingly innocent, such as x being assigned the value of z, as if y were zero. It may also result in something much more serious, such as the value of x becoming something strange, or, more likely, a JavaScript error occurring. This leads to the following common sense rule.

Initialize all JavaScript variables to meaningful default values. If a variable has no meaningful default, initialize it to null.

Implicit Data Types in JavaScript
There are five major implicit data types in JavaScript. A JavaScript value may be as follows:

A number, such as -5, 0 or 3.3333
A string, such as "Click Here" or "JavaScript"
One of the logical values true or false
A "non-atomic" JavaScript element, such as a function or object
The special value null
Actually, it would be more correct to say that there are five categories of data type, since it is possible to distinguish two different types of numbers (integers and floating-point numbers), and many different types of JavaScript objects, functions, and other structured types. In fact, Part II of those book, "JavaScript Objects," is entirely devoted to explaining the many different JavaScript objects.

Variables and Variable Names
It is very important to distinguish between variables and their values. The statement x = 10 contains two components: the variable x and the literal value 10. A literal refers to anything that is referred to directly, by its actual value. A variable is just an abstraction that provides a way of giving names to values. Thus the statement x = 10 says, "I am going to refer to the concrete (literal) quantity 10 by the abstract (variable) name x," just as you might say, "I am going to call this lumpy thing I'm sitting on a chair." This also leads to the following important piece of advice.
It is bad practice to change the implicit data type of a variable. If a variable is initialized to have a certain type (such as string) it should always have that type.

Thus, since we have started out with x = 10 we should make sure that x always has some numeric value. There is no rule that prohibits us from later saying x = "Fortran", but this will generally lead to confusion or programming errors in most cases. No one will stop you from calling that lumpy thing you are sitting on "bacon and eggs" but many of your guests may become confused if you do so.

One final rule about variable names: a valid JavaScript variable name must begin with a letter or with the underscore character (_). Case is important, so that norl, NoRl, NORL, and _NORL are all valid JavaScript variable names that refer to different variables.

Numerical Values
There are two numeric types in JavaScript: integers and floating-point numbers. The rules for specifying both types are almost identical to those of C or C++ or Java. Integers may be specified in base 10 (decimal), base 8 (octal), or base 16 (hexadecimal) formats. The three forms are distinguished as follows, based on the first one or two characters:


1-9 followed by any set of digits is a decimal integer.
0 followed by any set of the digits 0-7 is an octal integer.
0x or 0X followed by any of 0-9, a-f, or A-F is a hexadecimal integer.
Any of the three forms can also start with a + or - sign. Thus,
-45 is a decimal integer, 017 is an octal integer, and 0x12EF5 is a hexadecimal integer. The minimum and maximum integers that can be used are implementation dependent, but at least 32 bits should be expected.

Floating-point numbers can be specified in either the standard decimal point (".") format or the engineering E-notation. Typical floating-point numbers should contain a decimal point or an exponent, which may begin with either e or E. A floating-point number may also have a + or - sign. 0.0, -1.4e12, and 3.14159 are all valid floating-point numbers. The range of valid floats is again implementation dependent, but you should expect that any valid short floating-point number, as defined by the IEEE standard, is acceptable. (The IEEE is the Institute of Electrical and Electronics Engineers, a professional and standards-making organization.)

Note that the original LiveScript language attempted to treat all the numeric types the same. Since it has become JavaScript there has been a convergence toward the numerical types of the Java language, and the distinction between integer values, such as 5, and floating-point (or real) values, such as 3.3333, has increased.

LiveScript is now completely obsolete. It has been replaced by its descendant, JavaScript. Avoid any code you encounter labeled LiveScript as it will almost certainly not work correctly.

Strings
In JavaScript, strings may be specified using either single quotes ('stuff') or double quotes ("otherstuff"). If you begin a string with one type of quote you must end it with that same form of quote-for example, "badstuff' is not a legal string in JavaScript. Strings may also be nested by alternating the types of quotes used. In fact, you must alternate single and double quotes if you wish to put one string inside another. Here is an example of several nested strings:

"Oh, its 'Tommy this' and 'Tommy that' and 'throw im out, the brute'"
As in C and Java, JavaScript strings may contain special combinations of characters, known as escape sequences, to denote certain special characters. The rules for this are still emerging, but it is probably safe to assume that all the escape sequences defined in C will be supported. Since you will almost always be using formatting directives of HTML (such as <BR> for a line break) you will probably not use these directives very often. At the moment, the following sequences are supported:.

\t tab
\r line feed
\n return
\f form feed (vertical tab)
\b backspace

The special string "" or '' represents the zero length string. This is a perfectly valid string whose length is zero. This is the shortest JavaScript string; the length of the longest is, as usual, implementation dependent. It is reasonable to expect that most JavaScript environments will permit very long sonnets (or very short legislative measures) to be represented as single strings.

Logical Values
The logical, or Boolean, values true and false are typically used in expressions that test some condition to determine how to proceed. If that condition is met then one set of statements is executed; if it is not then another set is used instead. The first corresponds to the true condition, while the second represents the false condition. Not surprisingly, such expressions are known as conditional expressions. As you will see in the "Operators" section there are several comparison operators, such as the equality test (==), which result in logical values.

It is possible to think of true as 1 and false as 0. In fact, JavaScript converts these logical values into 1 and 0, respectively. JavaScript also accepts any non-zero integer in place of true, for example, so that 5 and -3 can both be used as stand-ins for true. Many different programming languages follow this same convention. It should be avoided in JavaScript, as it can lead to type confusion.

The Value null
The value null has a very special role in the JavaScript language. It is the value of last resort, so to speak, for every variable. For the beginning JavaScript programmer, its primary role will be in initializing variables that do not have any more meaningful initial value. For example, in the set of variable declarations given in the "Variables and Values" section, to initialize y to some value, we should have actually written

var y = null
This prevents JavaScript errors that arise when an uninitialized variable is accidentally used in an expression that requires a value. It is important to realize that the value null does not give the variable y any implicit data type. null also has the property that it may be converted to a benign form of all the other types. When it is converted to a number it becomes 0, when it is converted to a string it becomes the empty string "", and when it is converted to a Boolean value it becomes false. This is the one case where is it permissible to change the implicit data type of a variable after it is declared.

Therefore, statements such as

var lk2 = lk + y
var w = x + y
result in lk2 having the value "lucky" (the same as lk) and w having the value 10 (the same as x). This is why the value null is an excellent way of initializing variables-it is guaranteed to be harmless.

Type Conversion
Several of the examples in the previous section use the + operator to combine different types of things. You may recall that when a string is combined with a number in the form

stringthing + numberthing
the number is converted to a string and the + operator then glues the two strings together (concatenation). However, if they are combined in the opposite order

numberthing + stringthing
then JavaScript attempts to convert the stringthing to a number and add it, numerically, to numberthing. If the stringthing can be converted to a string, such as "-14," then all goes well; if it cannot then an error results. This illustrates the concept of implicit conversion in JavaScript.

We have already seen that some examples of implicit conversion are completely safe. false can be converted to 0, "5" can be converted to 5, and null can be converted to just about anything. However, some conversions are obviously invalid, and others might be questionable. Questions such as, "May the string '3.0' be legitimately converted to the integer 3?" are actually very difficult to answer with complete generality.

There are two approaches to handling this complex issue: use explicit conversion whenever possible, and use implicit conversion with great care. Both approaches should be used.

Use implicit conversion only when converting to a string form. Never use it to convert to numerical form. This is because attempts to convert a non-numerical quantity to a numeric form cause serious JavaScript errors, while conversion to string form generally do not.
You have probably already noticed that conversion to a string is always safe, at least for the data types we have encountered so far. In fact, this type of implicit conversion is a boon to the JavaScript programmer, since it avoids the tedious formatting directives that are necessary in many languages such as C. In JavaScript we can say

"This page has been accessed " + cnt + " times today"
without having to worry about the data type of the variable cnt. This construction will always give a valid string, and never an error.

The preceding Caution is also based on standard principles of defensive programming. There are many things that cannot be sensibly converted to a numerical form, so the prudent approach is to never try to implicitly convert anything to a number. There are several more robust approaches that can be used in case we have a string that we want to convert to numerical form. These are described in chapter 5. We will also see other exceptions to this rule as our mastery of JavaScript deepens.

Statements and Operators
The basic unit of work in JavaScript is the statement, as is the case in most programming languages. A JavaScript statement accomplishes work by causing something to be evaluated. This can be the result of giving a value to a variable, by calling a function, by performing some sort of calculation, or any combination of the. We have already seen variable declaration statements, which not only create (declare) a new variable, but also give it an initial value, such as the following statement:

var x = 10
JavaScript programs, as mentioned at the beginning of this chapter, are collections of statements, typically organized into functions, which manipulate variables and the HTML environment in which the script itself works, in order to achieve some goal.

The Structure of JavaScript Statements
Before plunging into a detailed description of the various types of statements and the operators they use, let's examine one simple statement in excruciating detail. Consider the statement

y = x + 5
This statement contains three parts: the result y, the operator = and the expression x + 5. The result always occurs in the left side, since JavaScript always operates from left to right, and is often called the lvalue. The result must always be something that can be modified. It would be erroneous to write null = x + 5, for example, because null is a built-in, unchangeable component of JavaScript itself-it cannot be modified, so it can never appear as a result.

The operator = is the assignment operator, of course. It causes the expression on the right to be evaluated and its value given (assigned) to the result. The expression x + 5 contains another operator, the + operator, which acts to combine x and 5 in some context-specific way. Since x is a number in this case, the + operator performs ordinary addition, and y gets the value 15. As we have already seen, if x had been a string, such as "bleh", then + would have acted as a string concatenation operator and y would be given the value "bleh5" instead. This is an example of operator overloading-the + operator can do different things in different situations. Many JavaScript operators are overloaded.

There is one final point to be made about this statement, and about the structure of JavaScript programs in general. JavaScript has adopted a line oriented approach to program flow. This means that it knows that a statement has ended when it reaches the end of a line. It is also possible to explicitly terminate a statement with a semicolon character (;). The statement y = x + 5; is identical in effect to the statement y = x + 5. This also means that you can, in fact, put multiple statements on a single line by separating each of them with a semicolon.

For those just starting out in JavaScript it is often a good idea to terminate each statement with a semicolon, and to also put only a single statement on each line. This might seem both redundant and extraneous, but it is well justified. The end of a line is often a purely visual concept. Anyone who has ever used a word processor has undoubtedly encountered the situation where a very long line looks like two lines. Different platforms (Macintosh, PC, UNIX) also have their own unique ideas as to what the proper end-of-line characters are. It is much safer to put in the extra semicolon character and be explicit about the end of the statement than it is to rely on one's eyesight.

Operators
The set of operators that JavaScript uses is, once again, very similar to that of the C, C++, and Java languages. It provides a number of different ways of combining different values, both literals and variables, into expressions. Some operators require two elements to participate in the operation, and are referred to as binary operators. The + operator is a binary operator. Other operators require only a single participant (operand), and are known as unary operators. The ++ operator, which adds 1 to its operand, is a unary operator. Operators may also join forces to form aggregate operators, as we shall see next.

JavaScript operators may be classified into the following groups:

Computational operators
Logical operators
Bitwise operators
Assignment and aggregate operators


Computational Operators
The computational operators are addition (+), subtraction and negation (-), division (/), multiplication (*), modulus (%), increment (++), and decrement (--). These operators are often used in performing arithmetic computations, but do not forget that the + operator is overloaded; it also has the extremely important role of string concatenation.

The first five computational operators have their standard mathematical meanings. They add, subtract, divide, or multiply two numeric quantities. By combining two quantities using one of these operators the result is made as precise as possible. If an integer is added to a floating-point number, the result is a floating-point number. The following four statements illustrate the use of these operators:

x = 4 + y;
y = 5.5 - z;
z = 10 / w;
w = 1.4e5 * v;
Note that division of integer quantities result in an integer result, so that if w had the value 4 in the third statement, z would get the value 2, not 2.5. Note also that the - operator may also be used as a unary operator to compute the negative of a numeric quantity:

n = -m;
This has exactly the same effect as if we had multiplied m by -1.

The modulus operator (%) is used to compute the remainder from a division. Although it can be used with floating-point numbers, it is typically used with integers, so that 21 % 4 evaluates to 1. The modulus operator always gives a remainder that has the same sign as the corresponding quotient, so that -21 % 4 evaluates to -1, not 3.

The increment and decrement operators are conveniences created to simplify the very common operations of adding or subtracting one from a number. Both these operators are unary and come in two forms: prefix and postfix. The expression ++x is the preincrement form of the ++ operator, while x++ is the postincrement form. This leads to a subtle and often misunderstood point about the increment and decrement operators.

Supposing that x has its usual value 10, consider the two statements

y = ++x;
z = x++;
These look very similar, but are in fact very different. After both of these statements have been executed, x has the value 11. However, y ends up with the value 11 while z has the value 10. Why? The reason has to do with the complex issue of what order the operators ++ and = are evaluated in these two statements. In the first statement, the ++ is evaluated first, so that x attains the value 11, and then the assignment = is evaluated, so that this value is passed on to y. In the second statement, the assignment operator = is applied first, so that z becomes 10, the current value of x, and then the ++ is applied to x, so that it advances to 11. The same rule applies to the decrement operator (--).

This might seem like it is a violation of the rule of left-to-right evaluation, and it is. Even though the equal sign is to the left of the preincrement operator (++) in the first statement, the ++ operator takes effect first. This is an example of operator precedence, the order in which multiple operators are applied. This complex topic is discussed in more detail in the "Order of Evaluation" section later in the chapter.

Logical Operators
Logical operators in JavaScript are used either to carry out some form of test, or to combine the results of more than one such test. They are often referred to as conditional operators. The logical operators that perform a test of some sort are the equality/inequality operator (== and !=), the comparison operators (<, <=, >, and =>), and the logical negation operator (!). The operators that combine logical values are logical AND (&&) and logical OR (||). Finally, the conditional operator (?) and the comma operator (,) are also combining operators, although they are only vaguely logical operators.

Equality Operators
The binary equality (==) and inequality (!=) operators are used to test if two quantities are the same or different. These operators are overloaded. On integers, they test for strict equality or inequality. On floating-point numbers, they test to see if the two quantities are equal within the precision of the underlying floating-point type. On strings, they test for exact equality-recall that case is significant in JavaScript strings. These operators all return a Boolean value, either true or false.

For example, if x has the value 10, y has the value 3.0, and z has the value "barney", then x == 10 is true, y != -5.0 is also true, and z == "fred" is false. Unfortunately, even operators as simple as these can be a source of error. It is regrettable that the logical operator == looks so much like the assignment operator =. Consider the following incorrect code fragment:

if ( x = 3 ) {
stuff...
The purpose of this code is almost certainly to test the value of the variable x against the constant 3, and execute the "stuff" if that test succeeded. This code fails to realize that purpose in two very dramatic ways, just by inappropriately using = instead of ==.

This type of error occurs in every programming language in which similar operators are used for very different purposes. In this case, we could have adopted another rule of defensive programming and said

if ( 3 = x ) {
stuff...
In this case, our typing mistake (= instead of ==) leads to an error, rather than resulting in a subtle programming flaw. Since 3 is a constant, it can never appear on the left side of an assignment, but it is quite capable of appearing on the left side of a logical test. Said another way, since x == 3 and 3 == x are completely equivalent, the form 3 == x is preferable. If it is mistyped as an assignment statement (3 = x) it leads to an immediate error rather than one which might take hours of debugging to uncover.

News and Comments Brought to you by: Geeks and Bloggers
The comments are owned by the poster. We aren't responsible for its content.