Section 26.3. JavaScript Syntax


26.3. JavaScript Syntax

Once 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. Statements

Each 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; 

File Size Versus Readability

Using whitespace to improve readability does have one drawback: increased file size. Each whitespace character (tab, space, carriage return, or newline) is still a character in the document. With lots of whitespace (and comments , for that matter), a script file can get quite large.

To balance the need for whitespace and comments for legibility and the desire for fast downloads, many JavaScript developers keep two copies of every script they work on: a "working" copy with whitespace intact and a production version, which is "compressed" by stripping out all unnecessary whitespace and comments.


26.3.2. Comments

Sometimes 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. Variables

Though 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 Types

JavaScript 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. Strings

Strings 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. Numbers

Numeric 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. Booleans

Booleans 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. Arrays

Arrays 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:

  • We establish the variable cats as an array with two members.

  • The first member is indexed as sabine and is, itself, an array of mixed data about her.

  • The second member is indexed as dakota and is an array of mixed data about him.

  • We then declare a new array (using shorthand) called reps and create a member indexed as sheldon containing mixed data about him.

  • Finally, we declare an array called animals and assign the variables cats and reps to be members of that array, indexed as cats and reptiles, respectively.

26.3.5. Operators

There are two categories of operators in JavaScript , arithmetic (or mathematical) and comparison .

26.3.5.1. Arithmetic operators

As 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' 

When concatenating numbers with strings, the result is always a string.


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 operators

The 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).

Table 26-1. Comparison operators for equality

Operator

Meaning

>

Greater than

<

Less than

==

Equal to

!=

Not equal to

>=

Greater than or equal to

<=

Less than or equal to


There are also comparison operators that are used to assert identity (see Table 26-2).

Table 26-2. Comparison operators for identity

Operator

Meaning

===

Identical to

!==

Not identical to


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 Structures

There are numerous control structures available to you in JavaScript. They are broken up into a few broad categories: conditionals, loops, switches, and functions.

On alert

alert is a helpful tool for alerting you to certain events occurring in your code. It creates a little dialog box with whatever statement you passed, along with an "OK" button that you can use to close it.

alert( 'send this message' );

For times when you only want a little information, this can be very helpful, but if you are calling alert many times throughout a large script, it can get a little frustrating to have to close each of the dialog boxes as they appear. Several tools have been developed to aid in JavaScript debugging that assist you in outputting information to the screen without using alert( ). On the simple end, there is jsTrace (www.easy-designs.net/code/jsTrace/), a port of the ActionScript trace window, and for more robust debugging, there is fvLogger (www.alistapart.com/articles/jslogging), which is very similar to the JavaScript Console that comes with most Mozilla-based browsers and Opera.


26.3.6.1. Conditional statements

There 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).

Table 26-3. Logical operators

Operator

Meaning

&&

and

||

or

!

not


"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. Loops

Loops 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. switch

Now 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. Functions

Now 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 do not need to return a value.


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. Objects

JavaScript 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.

What Is this?

this is a reserved keyword in JavaScript that has many uses but is often poorly understood.

In the scope of an object, this is used to make the object reference itself. It is the owner of the property or method. Such is the case with:

     function Cat( name, age ){       this.name = name;       this.age  = age;     } 

What this code does is set the name property of the Cat object (Cat.name) equal to the argument passed the Cat object as name. The same goes for age. this can also be used to assign methods to an object that are external to it. Take this example:

     function Cat( ){       this.purr = purr;     }     function purr( ){       alert('purrrrrrrrr');     } 

this can also be used to refer to the owner of a function. This usually occurs when handling events, but it is where things can get really confusing.

The default owner (or this) of any function is the window, but there are ways of attaching a function to an event (onclick, for example) that can make this reference the element whose action it is associated with. Take the following code:

     function change( ){       this.style.color = '#ff0000';     }     element.onlick = change; 

By assigning a function to an event in this way, we are copying the entire contents of change( ) to the onclick of element. Whereas, if we were to assign it like this:

     function change( ){       this.style.color = '#ff0000';     }     element.onlick = function( )(       change( );     }; 

we would only be referencing the function, and this would still reference the owner of change( ): window. When it was triggered, the function would likely not produce the desired effect.

To ensure that event-driven functions always target the intended element, it is recommended that you pass a reference to it:

     function change( obj ){       obj.style.color = '#ff0000';     }     element.onlick = function( )(       change( this );     }; 

By adding this simple fix, we can rest assured that our functions will behave as we intend them to and limit any possible confusion with this.


Table 26-4. Native objects and their commonly accessed methods

Object

Property or method

Use

Array

length

Sets or returns the number of members in an array

 

concat( )

Joins two or more arrays and returns the result

 

join( )

Puts all the members into a string, separated by the specified delimiter

 

pop( )

Removes and returns the last element of an array

 

push( )

Adds one or more members to the end of an array and returns the new length

 

reverse( )

Reverses the order of the members in an array

 

shift( )

Removes and returns the first member of an array

 

slice( )

Returns selected members from an existing array

 

sort( )

Sorts the members of an array

 

splice( )

Removes and adds new members to an array

 

unshift( )

Adds one or more members to the beginning of an array and returns the new length

Date

Date( )

Today's date and time

 

getdate( )

The day of the month

 

geTDay( )

The day of the week

 

getFullYear( )

The year, as a four-digit number

Math

abs(x)

Returns the absolute value of a number

 

ceil(x)

Returns the value of a number rounded up to the nearest integer

 

floor(x)

Returns the value of a number rounded down to the nearest integer

 

max(x,y)

Returns the number with the highest value of x and y

 

min(x,y)

Returns the number with the lowest value of x and y

 

random( )

Returns a random number between 0 and 1

 

round(x)

Rounds a number to the nearest integer

String

length

Returns the number of characters in a string

 

concat( )

Joins two or more strings

 

indexOf( )

Returns the position of the first occurrence of a specified string value in a string

 

lastIndexOf( )

Returns the position of the last occurrence of a specified string value, searching backward from the specified position in a string

 

match( )

Searches for a specified string value in a string

 

replace( )

Replaces some characters with others in a string

 

slice( )

Extracts a part of a string and returns the extracted part in a new string

 

split( )

Splits a string into an array of strings

 

substring( )

Extracts the characters in a string between two specified indexes

 

toLowerCase( )

Displays a string in lowercase letters

 

toUpperCase( )

Displays a string in uppercase letters


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( ); 




Web Design in a Nutshell
Web Design in a Nutshell: A Desktop Quick Reference (In a Nutshell (OReilly))
ISBN: 0596009879
EAN: 2147483647
Year: 2006
Pages: 325

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net