26.3. JavaScript SyntaxOnce you get the hang of it, JavaScript can be a very easy language to write. In fact, it is very similar to other common web languages, including ActionScript (which is itself an ECMA scripting language and is the underlying language of Flash) and PHP (which is a server-side scripting language). We'll begin with the basics of syntax. 26.3.1. StatementsEach script we write consists of a series of statements . Statements can be terminated with a line break first statement second statement or with a semicolon (;) first statement; second statement; For readability, and to avoid potential statement termination problems, it is recommended that you use both: first statement; second statement;
26.3.2. CommentsSometimes it is helpful to make notes for yourself to keep track of what is going on in a script. As in HTML, JavaScript allows you to make comments in your code but offers a few different ways to do it. The first style of comment uses two forward slashes: // this is a comment This type of comment makes the interpreter ignore the remainder of the line. The second method allows you to comment out multiple lines: /* this is a multi-line or block comment */ Apart from using comments to make notes to yourself, they are also quite useful in the debugging process: if you can't seem to figure out where an error is coming from, you can comment out a line or section of the code to see if it is the culprit. 26.3.3. VariablesThough not a strictly typed language, in JavaScript , you still need to declare variables before you begin using them. That said, you have a lot of flexibility in how you name and declare your variables. Variables are declared using the reserved keyword var. Variable names can be any length and contain numbers, letters, and certain non-alphanumerics. Arithmetic operators (+, -, *, /) and quotes (' and ") need to be avoided in variable names . You also need to watch that your variable names do not conflict with JavaScript's reserved keywords (this, for, function, etc.). A text editor with a good syntax highlighter should help you avoid those pitfalls. Variable names can be written in numerous cases and styles. And as JavaScript is case-sensitive, each of the following would be a unique variable: var MYVAR; // uppercase var myvar; // lowercase var myVar; // camel case var MyVar; // initial caps var MyVaR; // mixed case It is common practice to separate words in multiword variable (or function) names with an underscore or to write them in "camelCase": var my_cat; var myCat; You may consider writing all variables using one convention and all function names using the other to make it easier to distinguish them at a glance: var my_variable; function myFunction( ){ ... } Variables can also have their values assigned when they are declared: var cat = 'Sabine'; or not: var cat; You can also declare multiple variables (again with or without value assignment) simultaneously: var girl_cat = 'Sabine', boy_cat = 'Dakota', tortoise; 26.3.4. Data TypesJavaScript variables can be one of several different data types . Those data types fall into two different categories: scalars and arrays . Scalar variables have one value at a time. That value can be a string, a number, or a Boolean. Arrays can contain multiple values. We will discuss each type in turn. 26.3.4.1. StringsStrings are enclosed by either single (') or double (") quotes and can contain zero or more characters: var empty = ''; var girl_cat = 'Sabine'; var boy_cat = "Dakota"; var zip_code = '06517'; Your string can also contain quotes, but you need to be careful to escape any quotes that match the quotes you are using to enclose your string: var my_string = 'This "quoted text" is fine'; my_string = "This 'quoted text' is fine"; my_string = 'This string\'s "quote" is escaped'; my_string = "This string's \"quotes\" are escaped'; It can get a little confusing if you don't maintain some form of consistency. Most JavaScript developers tend to use single quotes to wrap strings . This is likely a holdover from other languages where double-quoted strings are processed differently than single-quoted ones. 26.3.4.2. NumbersNumeric values are pretty self-explanatory, but here are a few examples var my_age = 28; var birth_year = 1977; var negNum = -1.9304; 26.3.4.3. BooleansBooleans are true/false values. They can be represented by the keywords true or false (without quotes around them) or the numbers 1 and 0, respectively: var bald = false; // I am not bald (yet -- fingers crossed) var bearded = 1; // I do have a beard 26.3.4.4. ArraysArrays allow you to group multiple values (called members) in a single variable. Standard array values are numerically indexed beginning with 0 and counting upward. They can be declared in a few different ways as well: var array_1 = new Array( ); // empty array var array_2 = new Array(2); // array with two undefined members var array_3 = []; // shorthand empty array As with scalars, an array's values can be set when it is declared: var cats = new Array( 'Sabine', 'Dakota' ); var names = [ 'Aaron', 'Kelly' ]; or the values can be assigned afterward: var cats = new Array( ); cats[0] = 'Sabine'; cats[1] = 'Dakota'; An array can contain any sort of data in its members: var sabine = [ 'cat', 'female', 9, true ]; // Sabine is a 9-year-old female cat that is spayed even other arrays : var cats = new Array( 2 ); cats[0] = [ 'Sabine', 'cat', 'female', 9, true ]; cats[1] = [ 'Dakota', 'cat', 'male', 8, true ]; An array member can also have its value assigned by a variable: var cats = new Array( 2 ); var sabine = [ 'cat', 'female', 9, true ]; var dakota = [ 'cat', 'male', 8, true ]; cats[0] = sabine; cats[1] = dakota; Associative arrays are a specialized form of array (sometimes referred to as a "hash") that use keywords as their indexes. The following example uses a few different forms of arrays and scalars: var cats = new Array( 2 ); cats['sabine'] = [ 'cat', 'female', 9, true ]; cats['dakota'] = [ 'cat', 'male', 8, true ]; var reps = []; reps['sheldon'] = [ 'tortoise', 'male', 5, false ] var animals = []; animals['cats'] = cats; animals['reptiles'] = reps; Got all that? If not, here's a little translation:
26.3.5. OperatorsThere are two categories of operators in JavaScript , arithmetic (or mathematical) and comparison . 26.3.5.1. Arithmetic operatorsAs you can probably guess, arithmetic operators are used to perform mathematical functions: var add = 1 + 1; // 2 var subtract = 7 - 3; // 4 var multiply = 2.5 * 2; // 5 var divide = 4 / 2; // 2 These arithmetic operators can also be applied to variables with numeric values: var my_num = 1 + 1; // 2 var new_num = my_num * 5; // 10 var my_arr = Array( 2, new_num ); // an array of numeric values var big_num = my_arr[0] * my_arr[1]; // 20 In addition to addition, the + operator has another purpose: concatenation. Concatenation is the combining of two or more values into a new value. It is usually applied to strings: var sentence = 'This is one phrase' + ' ' + 'and this is another' + '.'; but also applies to combining numbers and strings: var new_str = 10 + '20'; // '1020'
There are also a few shorthand arithmetic operators you can use in specific cases, such as having a string or number add to itself: var str = 'Hello there'; str += ', pilgrim.'; // 'Hello there, pilgrim.' var num = 2; num += 2; // 4 There is a shorthand for incrementing or decrementing a number by one: var num = 2; num++; // 3 num--; // 2 26.3.5.2. Comparison operatorsThe other type of operators available in JavaScript are comparison operators . They are used to make assertions about the equality of two values (see Table 26-1).
There are also comparison operators that are used to assert identity (see Table 26-2).
To understand what identity is, take a look at two variables: var bool = true; var num = 1; bool is true, which is a Boolean value, and num is 1, a numeric value. If you recall back to the discussion of Booleans, however, you may recall that 1 and 0 are aliases for true and false, respectively. Therefore: bool == num; /* bool is equal to num -or- true and 1 are equal */ An identity-check, however, allows you to tell the two apart: bool !== num; /* bool is not identical to num -or- true is not identical to 1 */ and that is why identity comparison operators are nice to have in your toolbox. 26.3.6. Control StructuresThere are numerous control structures available to you in JavaScript. They are broken up into a few broad categories: conditionals, loops, switches, and functions.
26.3.6.1. Conditional statementsThere are a few different ways to handle conditional statements . The first is the simple if statement. It tests a condition and then, if the condition is met, it executes: if( 2 < 1 ){ alert( 'Something is wrong' ); } This same statement could also be written in shorthand (without the curly braces): if( 2 < 1 ) alert( 'Something is wrong' ); If you wanted to know the outcome either way, you would use an if...else statement: if( 2 < 1 ){ alert( 'Something is wrong' ); } else { alert( 'Everything is fine' ); } You can also write this in shorthand, using what is called the ternary operator: ( 2 < 1 ) ? alert( 'Something is wrong' ) : alert( 'Everything is fine' ); The ternary operator functions like this: ( test condition ) ? statement if true : statement if false; and can even be used for value assignment to variables: var total = ( money > 1000000 ) ? 'over $1Million' : 'less than $1Million'; Now, suppose you wanted to know if one or more conditions were met. You could use an if...else if statement: if( height > 6 ){ alert( 'You\'re tall' ); } else if( height > 5.5 ){ alert( 'You\'re average height' ); } else { alert( 'You\'re shorter than average' ); } or a switch statement: switch( true ){ case ( height > 6 ): alert( 'You\'re tall' ); break; case ( height > 5.5 ){ alert( 'You\'re average height' ); break; default: alert( 'You\'re shorter than average' ); break; } In each of these instances, a comparison is performed, and if the condition is not met, the next comparison is tried. A switch statement is a little different than a traditional conditional statement, and it acts almost like a hybrid of a conditional and a loop (which we will discuss momentarily). In a switch statement, each case is tested against the argument of the switch and if they are equal, the statements in that case are evaluated and the switch is exited (using break). In the above example, the argument is true, so the first case to test true will be evaluated (in this case, triggering an alert). We will examine more switch statements below. There are a few operators we have not discussed yet as they come more into play when you are working with control structures. They are called logical operators and there are three of them: and, or, and not (see Table 26-3).
"Not" should already be somewhat familiar to you from the comparison operators "not equal to" and "not identical to." It is used to negate a statement or condition or group of either: if( !(num < 10) ){ alert( 'num is greater than 10' ); } "And" and "or" are used to group conditions together so you can ensure they are either both met or at least one is: if( (num > 10) && (num < 20) ){ alert( 'num is between 11 and 19' ); } if( (num <= 10) || (num >= 20) ){ alert('num is not between 11 and 19' ); } The second example above could also be rewritten using the logical operator "not" in combination with "and": if( !(num > 10) && !(num < 20) ){ alert( 'num is not between 11 and 19' ); } Or, we could use some additional parentheses to group the conditionals, negating them both at once: if( !( (num > 10) && (num < 20) ) ){ alert( 'num is not between 11 and 19' ); } As you can see, there's more than one way to test the same condition. 26.3.6.2. LoopsLoops are another group of control structures, normally used to keep your code smaller by evaluating a statement or collection of statements a specified number of times. Let's say we want to alert a countdown from 10 to 0. Without loops, we'd have to write: var i = 10; alert( i ); i--; // 9 alert( i ); i--; // 8 alert( i ); i--; // 7 alert( i ); i--; // 6 alert( i ); i--; // 5 alert( i ); i--; // 4 alert( i ); i--; // 3 alert( i ); i--; // 2 alert( i ); i--; // 1 alert( i ); i--; // 0 alert( i ); That's 22 lines of code and a lot of repetition. Using loops we can perform the same task. First let's see how we'd do it with a simple while loop: var i = 10; while ( i >= 0 ){ alert( i ); i--; } Using while, we were able to compress the whole thing down to five lines, which is pretty cool. What while does is test the condition set in the argument and then perform the statements within its curly braces over and over until the condition is no longer met. In pseudocode, that looks like this: initialize; while( condition ){ statement; alter condition; } It is important to remember, when dealing with loops, that you need to pay attention to both your condition and how you alter your condition to make sure you loop will not execute ad infinitum. For example: var i = 11; while( i > 10 ){ i++; } alert( i ); /* this statement is never reached because the while loop's condition is always met */ A similar loop type is do...while. The difference between do...while and while is that a do...while loop is executed at least once, whereas a while loop may never execute at all: var i = 10; while( i > 10 ){ i--; } alert( i ); // 10, the while loop never executed do{ i--; }while( i > 10 ) alert( i ); // 9, because the do...while loop executed once Here's the pseudocode for a do...while loop: initialize; do{ statement; alter condition; }while( condition ) A do...while loop won't really shorten our countdown, but another loop type will. It is the for loop and is perhaps the most common of all loop types. To rewrite our countdown requires only three lines of code: for( var i = 10; i >= 0; i-- ){ alert( i ); } That may seem a little odd, but it is really quite simple. Take a look at the pseudocode: for( initialize; test condition; alter ){ statement; } To glance back at our example, what we did was initialize the for loop by declaring the variable i to be equal to 10. We then say we want the loop to run as long as i is greater than or equal to 0. Finally, we say that we want i to be decremented each time an iteration of the loop completes. You will use for loops quite often when working with arrays , as they are useful for iterating through its members, usually in the form for( var i=0; i < some_array.length; i++ ){ // do something } This example also serves as a good introduction to object properties, which will be discussed in a moment. length is a property of arrays that tells you how many members an array has. There is a slight variant of the for loop called a for...in loop. This is very similar to the for loop, but it loops through all of the members of an array without the need for initialization, condition, or alteration. The pseudocode for a for...in loop is as follows: for( member in array ){ statement involving array[member]; } There are several nice things about for...in loops: they work well for iterating through both normal arrays and associative arrays, and you don't need to know the length of the array you are iterating through. 26.3.6.3. switchNow that you understand a few more control structures, it's time to revisit the switch statement. As you saw in the previous switch example, each case within a switch is tried and, if it matches the argument of the switch, its statements are evaluated and the switch is exited (via break). There is also normally a default case (simply called default) that can act as a fallback (or an error alert) if none of the other cases are met. To demonstrate the power of the switch, let's spice up the countdown loop a bit: for( var i=10; i >=0; i-- ){ switch( i ){ case 2: alert( 'Almost...' ); break; case 1: alert( 'There...' ); break; case 0: alert( 'BOOM!' ); break; default: alert( i ); break; } } This code would initiate a countdown from 10 to 0, alert-ing each number, but replacing 2 with Almost..., 1 with There..., and 0 with BOOM!. 26.3.6.4. FunctionsNow things get a little more interesting. Functions allow you to create discrete bits of reusable code, which you can call at any given time. These will make up the bulk of what you write in JavaScript. Creating a function is easy. Here's the pseudocode for making one: function functionName( arguments ){ statements; } The function keyword designates the block as a function, and the arguments can be either a single variable or a comma-separated list of variables. Let's make a basic one and then put it to use: function addThese( a, b ){ var combination = a + b; return combination; } var my_var = addThese( 2, 10 ); // 12 var my_str = addThese( 'A', ' string' ); // 'A string' The function we created adds/concatenates the two supplied arguments and then returns that new value using the return keyword.
Functions can also be unnamed. These functions , called anonymous functions, are usually either assigned to a variable for use as objects or are used in event handling, both of which we will discuss shortly. Before we move on, it is important to touch on the concept of variable scope. In JavaScript there are two kinds of variables: global and local . Global variables are initialized outside of any functions and are available for any function to use. Local variables are those variables that are declared within a function. No other functions will have access to those variables. The var keyword plays an important role in determining variable scope. Let's take a look at a quick example: function square( num ){ total = num * num; return total; } var total = 50; var number = square( 20 ); alert( total ); In this instance, the alert-ed value will be 400. The reason for that is that the square function sets the variable total equal to the argument2 (squared). total is initialized outside of the function, so it's value is changed from 50 to 400 when the square() runs. To keep the value of the global total from changing, we need to make the total variable used in the function a local variable: function square( num ){ var total = num * num; return total; } var total = 50; var number = square( 20 ); alert( total ); 26.3.7. ObjectsJavaScript is an object-based language and as such, many of its components are themselves objects . Some of the native objects in JavaScript we've already discussed: Array and Function. Some others are Element, Math, and Date. You can also create custom objects, which we'll get to in a moment. An object is essentially a self-contained collection of data. There are two data types available to it: properties and methods. Properties are values, while methods are functions. What makes objects useful is that they share access to their properties and methods. Let's look at two examples of the built-in JavaScript objects in action: var num = 1.76543; num = Math.round(num); // 2 var now = new Date( ); var days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; var day = days[ now.getDay( ) ]; alert( 'Today is ' + day ); In the first example, we used a method of the Math object to round our variable up. In the second example, we created a new instance of the Date object and then used its getday( ) method to tell us what today is by selecting the day name from an array of day names (the geTDay( ) method returns the index number of the weekday, 0 through 6 starting with Sunday, which is why that worked). Table 26-4 has a listing of a few native JavaScript objects and their most commonly used properties and methods.
Now let's make a custom object, Cat, and provide two properties to it: name and age. We can also define two methods for it: purr( ) and hiss( ). Let's take a look at the construction of that object: function Cat( name, age ){ this.name = name; this.age = age; this.purr = function( ){ alert( 'purrrrrrrrr' ); }; this.hiss = function( ){ alert( 'hissssssss!' ); }; } Now we can access the properties and methods of any Cats we create: var sabine = new Cat( 'Sabine', 9 ); var dakota = new Cat( 'Dakota', 8 ); alert( 'I should give Dakota ' + sabine.age + dakota.age + 'treats, because he is soooo good.' ); // that's 17 treats, by the way sabine.hiss( ); There are numerous ways to create objects. One, which has become quite common lately, is called an object literal. Here is the Cat object defined in that way: var Cat = { name: false, age: false, purr: function( ){ alert( 'purrrrrrrrr' ); }, hiss: function( ){ alert( 'hissssssss!' ); } }; As you can probably guess, this method is not nearly as flexible, as you can't create multiple instances of the Cat object. It can also be referred to as a singleton object as there can only be one instance of that object type. This approach is usually reserved for creating discrete objects that will not be replicated. Beyond that, however, the object's use is pretty much the same: Cat.name = 'Sabine'; Cat.age = 9; Cat.hiss( ); |