4.1 Overview of JavaScript

4.1 Overview of JavaScript
Originally developed by Netscape, as LiveScript
Became a joint venture of Netscape and Sun in 1995, renamed
JavaScript
,"&-.#/$0
Now standardized by the European Computer Manufacturers
Association as ECMA-262 (also ISO 16262)
!"#$%&'()'$*+$
1&2&3)/(-.
We’ll call collections of JavaScript code scripts, not programs
JavaScript and Java are only related through syntax
JavaScript is dynamically typed
JavaScript’s support for objects is very different
http://www.ecma-international.org/publications/standards/Ecma-262.htm
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
4.1 Overview of JavaScript (continued)
4.2 Object Orientation and JavaScript
JavaScript can be used to:
JavaScript is NOT an object-oriented programming language
•
•
Does not support class-based inheritance - cannot support
polymorphism
replace some of what is typically done with applets
(except graphics)
replace some of what is done with CGI - namely serverside programming (but no file operations or networking)
Has prototype-based inheritance, which is much different
JavaScript objects are collections of properties, which are like the
members of classes in Java and C++
JavaScript is the primary language for Ajax
User interactions through forms are easy
JavaScript has primitives for simple types
The Document Object Model makes it possible to support
dynamic HTML documents with JavaScript
The root object in JavaScript is Object – all objects are derived from
Much of what we will do with JavaScript is event-driven
computation - wait until Chapter 5
All JavaScript objects are accessed through references
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
2
Object
3
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
4
JavaScript and JAVA
Browsers and XHTML/JavaScript Documents
• What happens when the browser encounters a
JavaScript script in a document?
• JAVA is strongly typed - types are known at compile
time and operand types (!"#$% !&'&(!)*+) are
checked for compatibility
• Two approaches for embedding JavaScript in
XHTML documents:
• Variables in JavaScript are dynamically typed
– Explicit embedding (,-!. &+(*µ/!*(-)
– Implicit embedding (0#1,,-!- &+(*µ/!*(-)
– Compile-time type checking impossible
• Objects in JAVA are static:
– their collection of data members and methods is fixed at
compile time
<script type = "text/javaScript">
-- JavaScript script –
</script>
• JavaScript objects are dynamic: members of an
object can change during execution
<script type = "text/javaScript"
src = "myScript.js">
</script>
• Both have similar syntax
5
Implicit vs Explicit JavaScript
6
JavaScript embedding
• Scripts are usually hidden from browsers that do not
include JavaScript interpreters by putting them in
special comments:
• Explicit embedding:
– Mixes two types of notation inside the same document
(bad for readability)
– Makes maintenance difficult - often different people
manage the XHTML and the JavaScript
<!--
-- JavaScript script –
//-->
• Depending on its use, a JavaScript script that is
explicitly embedded appears in:
• This is also required by the XHTML validator
– The head of an XHTML document - for scripts that
produce content only upon request or for those that react
to user interactions
• Note that the comment closure is in a new line and is
also a JS comment
! These scripts contain function definitions and code associated with
form elements
– The body of an XHTML document - for scripts that are to
be interpreted just once, as they are found
7
8
JavaScript objects
4.3 General Syntactic Characteristics
• Objects are collections of properties:
- Language Basics:
– data properties (primitive values and references to objects)
– method properties (methods)
- Identifier form: begin with a letter or underscore,
followed by any number of letters, underscores,
and digits
- Case sensitive
- 25 reserved words, plus future reserved words
- Comments: both // and /* … */
• Objects are accessed indirectly through variables
– The properties of an object are referenced by attaching the
name of a property to the variable that references the object.
E.g. myCar.engine
• Objects are dynamic collections of property-value
pairs
– Properties are names
– Values are data values or functions
• All functions are objects and are referenced through
variables
9
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
4.4 Primitives, Operations & Expressions (continued)
4.4 Primitives, Operations & Expressions (continued)
All primitive values have one of the five primitive types: Number, String,
Boolean, Undefined, or Null
Boolean values are true and false
The only Null value is null
The only Undefined value is undefined
Number, String, and Boolean have wrapper objects (Number, String, and
Boolean)
JavaScript is dynamically typed – any variable can be used for
anything (primitive value or reference to any object)
In the cases of Number and String, primitive values and objects are
coerced back and forth so that primitive values can be treated
essentially as if they were objects
The interpreter determines the type of a particular occurrence of a
variable (values do have type)
Numeric literals – just like Java
Variables can be either implicitly or explicitly declared
All numeric values are stored in double-precision floating point
var sum = 0,
today = "Monday",
flag = false;
String literals are delimited by either ' or "
- Can include escape sequences (e.g., \t)
- All String literals are primitive values
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
10
11
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
12
4.4 Primitives, Operations, & Expressions (continued)
4.4 Primitives, Operations & Expressions (continued)
- String catenation operator : +
Numeric operators - ++, --, +, -, *, /, %
- All operations are in double precision
- Same precedence and associativity as Java
- Coercions (implicit type conversions)
- Catenation coerces numbers to strings
- Numeric operators (other than +) coerce strings to numbers (if either
operand of + is a string, it is assumed to be catenation)
The Math Object provides floor, round, max, min, trig functions, etc.
e.g., Math.cos(x)
- Conversions from strings to numbers that do not work return NaN
- Explicit conversions
1. Use the String and Number constructors
2. Use toString method of numbers
3. Use parseInt and parseFloat on strings
The Number Object collects useful properties that have constant values
- Some useful properties:
MAX_VALUE, MIN_VALUE, NaN,
POSITIVE_INFINITY, NEGATIVE_INFINITY, PI
- e.g., Number.MAX_VALUE
- String properties & methods:
- length e.g., var len = str1.length; (a property)
- charAt(position) e.g., str.charAt(3)
- indexOf(string) e.g., str.indexOf('B')
- substring(from, to) e.g., str.substring(1, 3)
- toLowerCase() e.g., str.toLowerCase()
An arithmetic operation that creates overflow returns NaN
- NaN is not == to any number, not even itself
- Test for it with isNaN(x)
- Number object has the method, toString
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
13
Chapter 4
14
© 2009 by Addison Wesley Longman, Inc.
4.4 Primitives, Operations & Expressions (continued)
4.5 Screen Output & Keyboard Input
- The typeof operator
- Returns "number", "string", or "boolean" for Number, String, or
Boolean, "undefined" for Undefined, "function" for functions, and
"object" for objects and for NULL
JavaScript models the XHTML document inside which a script is
embedded, as the Document object
The model for the browser display window is the Window object
- The Window object has two properties, document and window, which
refer to the Document and Window objects, respectively (window is selfreferential)
- Assignment statements – just like C++ and Java
- The Date Object
- Create one with the Date constructor (no params): var today = new
Date();
- Local time methods of Date:
toLocaleString – returns a string of the date
getDate – returns the day of the month
getMonth – returns the month of the year (0 – 11)
getDay – returns the day of the week (0 – 6)
getFullYear – returns the year
getTime – returns the number of milliseconds since January 1, 1970
getHours – returns the hour (0 – 23)
getMinutes – returns the minutes (0 – 59)
getMilliseconds – returns the millisecond (0 – 999)
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
- The Document object has a method, write, which dynamically creates
content
- The parameter is a string, often catenated from parts, some of which
are variables e.g.,
document.write("Answer: " + result +
"<br />");
- The parameter is sent to the browser, so it can be anything that can
appear in an HTML document (<br />, but not \n)
- The Window object has three methods for creating dialog boxes, alert,
confirm, and prompt
15
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
16
4.5 Screen Output (continued)
1. alert("Hej!
\n");
- Parameter is plain text, not HTML
- Opens a dialog box which displays the parameter string and an OK button
- It waits for the user to press the OK button
2. confirm("Do
you want to continue?");
- Opens a dialog box and displays the parameter and two buttons, OK and
Cancel
- Returns a Boolean value, depending on which button was pressed (it waits
for one)
3. prompt("What
is your name?", "");
- Opens a dialog box and displays its string parameter, along with a text box
and two buttons, OK and Cancel
- The second parameter is for a default response if the user presses OK without
typing a response in the text box (waits for OK)
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
18
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Chapter 4
- Similar to C, Java, and C++
- Compound statements are delimited by braces, but compound statements
are not blocks
- Control expressions – three kinds
// Get the coefficients of the equation from the user
1. Primitive values
- If it is a string, it is true unless it is empty or "0"
- If it is a number, it is true unless it is zero
var a = prompt("What is the value of 'a'? \n", "");
var b = prompt("What is the value of 'b'? \n", "");
var c = prompt("What is the value of 'c'? \n", "");
2. Relational Expressions
- The usual six: ==, !=, <, >, <=, >=
// Compute the square root and denominator of the result
- Operands are coerced if necessary
- If one is a string and one is a number, it attempts to convert the string
to a number
- If one is Boolean and the other is not, the Boolean operand is coerced
to a number (1 or 0)
var root_part = Math.sqrt(b * b - 4.0 * a * c);
var denom = 2.0 * a;
// Compute and display the two roots
var root1 = (-b + root_part) / denom;
var root2 = (-b - root_part) / denom;
document.write("The first root is: ", root1, "<br />");
document.write("The second root is: ", root2, "<br />");
© 2009 by Addison Wesley Longman, Inc.
22
4.6 Control Statements
// roots.js
// Compute the real roots of a given quadratic
// equation. If the roots are imaginary, this script
// displays NaN, because that is what results from
// taking the square root of a negative number
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
- The unusual two: === and !==
- Same as == and !=, except that no coercions are done (operands
must be identical)
E.g. ‘3’ === 3 evaluates to false
23
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
24
4.6 Control Statements (continued)
4.6 Control Statements (continued)
2. Relational Expressions (continued)
- Comparisons of references to objects are not useful
(addresses are compared, not values)
- Switch
switch (expression) {
case value_1:
// value_1 statements
case value_2:
// value_2 statements
…
[default:
// default statements]
}
3. Compound Expressions
- The usual operators: &&, ||, and !
- The Boolean object has a method, toString, to allow them
to be printed (true or false)
- If a Boolean object is used in a conditional expression, it is
false only if it is null or undefined
- The statements can be either statement sequences or compound
statements
- Selection Statements
- The control expression can be a number, a string, or a Boolean
- The usual if-then-else (clauses can be either
single statements or compound statements)
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
- Different cases can have values of different types
25
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
26
27
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
28
// borders2.js
// An example of a switch statement for table border
// size selection
var bordersize;
bordersize = prompt("Select a table border size \n" +
"0 (no border) \n" +
Document.write("<caption> 2008 NFL Divisional",
"1 (1 pixel border) \n" +
" Winners </caption>");
"4 (4 pixel border) \n" +
document.write("<tr>",
"<th />",
"8 (8 pixel border) \n");
switch (bordersize) {
case "0": document.write("<table>");
break;
case "1": document.write("<table border = '1'>");
break;
case "4": document.write("<table border = '4'>");
break;
case "8": document.write("<table border = '8'>");
break;
default: document.write("Error - invalid choice: ",
bordersize, "<br />");
}
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
"<th> American Conference </th>",
"<th> National Conference </th>",
"</tr>",
"<tr>",
"<th> East </th>",
"<td> Miami Dolphins </td>",
"<td> New York Giants </td>",
"</tr>",
"<tr>",
"<th> North </th>",
"<td> Pittsburgh Steelers </td>",
"<td> Minnesota Vikings </td>",
"</tr>",
"<tr>",
"<th> West </th>",
"<td> San Diego Chargers </td>",
"<td> Arizona Cardinals </td>",
"</tr>",
"<tr>",
"<th> South </th>",
"<td> Tennessee Titans </td>",
"<td> Carolina Panthers </td>",
"</tr>",
"</table>");
4.6 Control Statements (continued)
Object creation and Modification
- Loop statements
while (control_expression) statement or cmpnd
• Objects are often created with a new expression,
which must include a call to a constructor
• new creates a blank object - one with no properties
for (init; control; increment) statement or cmpnd
– JavaScript objects do not have types
– The constructor both creates and initializes object
properties. E.g., the following command creates an object
with some inherited method properties, but no data
properties:
- init can have declarations, but the scope of such
variables is the whole script
do
statement or compound
while (control_expression)
var my_car = new Object();
– The following command creates a blank object and assigns
two properties to the object:
var my_car = {make: “Ford”, model: “Contour”);
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
30
29
Object properties
Accessing object properties
• Created by assigning a value to a property’s name
• A property can be accessed the same way it is
assigned a value, namely with the object-dotproperty notation
my_car.make = “Ford”;
my_car.model = “Contour”;
my_car.engine = new Object(); -- Object nesting
my_car.engine.config = “V6”;
my_car.engine.hp = 200;
• Property names can be accessed also as if they
were elements of an array:
• Object properties are not variables - they are just
names of values, used with object variables to access
property values. E.g.:
for (identifier in object)
statement or compound
document.write(my_car.engine);
for (var prop in my_car)
document.write(“Name: ”, prop, “; Value:”,
my_car[prop] + "<br />");
• The number of properties in a JavaScript object is
dynamic - at any time during interpretation, properties
can be added to or deleted from an object.
delete(my_car.model);
31
32
4.8 Arrays
4.8 Arrays (continued)
- Objects with some special functionality
- Array elements can be primitive values or references to other objects
- Length is dynamic - the length property stores the length
- Array methods:
- join – converts all elements of an array to strings and
concatenates them into a single string e.g.,
var listStr = list.join(", ");
- Array objects can be created in two ways, with new, or by assigning an
array literal
- reverse
- sort – e.g., names.sort();
- Coerces elements to strings and puts them in alphabetical order
- concat – catenates its actual parameters to the end of the array
object e.g., newList = list.concat(47, 26);
- slice - similar to substring for strings
var myList = new Array(24, "bread", true);
var myList2 = [24, "bread", true];
var myList3 = new Array(24);
- The length of an array is the highest subscript to which an element has
been assigned, plus 1
myList[122] = "bitsy";
listPart = list.slice(2, 5);
listPart2 = list.slice(2);
- toString
// length is 123
- Because the length property is writeable, you can set it to make the
array any length you like, as in
- Coerce elements to strings, if necessary, and catenate them
together, separated by commas (exactly like join(", "))
- push, pop, unshift, and shift
myList.length = 150;
- Assigning a value to an element that does not exist creates that element
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
33
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
34
4.9 Functions
Variables
- function function_name([formal_parameters]) {
-- body –
• Variables can be implicitly or explicitly declared:
– Variables declared with a var statement are explicitly declarared.
– Other variables are implicit.
}
- Return value is the parameter of return
- If there is no return, or if the end of the function is reached,
undefined is returned
- If return has no parameter, undefined is returned
• Scope of a variable: the range of statements over which
the variable is visible.
• When JS is embedded in an XHTML document, the scope
of a variable is the range of lines of the document over
which the variable is visible.
– An implicitly declared variable has global scope, i.e. is
visible in the entire XHTML document or JS file. This is
true also for implicit variables defined inside a function
definition.
– Variables explicitly declared inside a function have local
scope.
- Functions are objects, so variables that reference them can be
treated as other object references
- If fun is the name of a function,
ref_fun = fun;
...
ref_fun(); /* A call to fun */
- We place all function definitions in the head of the the XHTML
document
35
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
36
4.9 Functions (continued)
function params(a, b) {
document.write("Function params was passed ",
arguments.length, " parameter(s) <br />");
document.write("Parameter values are: <br />");
- Parameters are passed by value, but when a reference variable is passed,
the semantics are pass-by-reference
- There is no type checking of parameters, nor is the number of parameters
checked (excess actual parameters are ignored, excess formal parameters
are set to undefined)
for (var arg = 0; arg < arguments.length; arg++)
document.write(arguments[arg], "<br />");
- All parameters are sent through a property array, arguments, which has the
length property
document.write("<br />");
}
- There is no clean way to send a primitive by reference
- One dirty way is to put the value in an array and send the array’s name
// A test driver for function params
function by10(a) {
a[0] *= 10;
}
...
var listx = new Array(1);
...
listx[0] = x;
by10(listx);
x = listx[0];
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
params("Mozart");
params("Mozart", "Beethoven");
params("Mozart", "Beethoven", "Tchaikowsky");
37
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
38
4.9 Functions (continued)
- To sort something other than strings into alphabetical order,
write a function that performs the comparison and send it to the
sort method
- The comparison function must return a negative number, zero,
or a positive number to indicate whether the order is ok, equal,
or not
function num_order(a, b) {return a - b;}
- Now, we can sort an array named num_list with:
num_list.sort(num_order);
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
39
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
40
4.11 Constructors
function median(list) {
list.sort(function (a, b) {return a - b;});
var list_len = list.length;
- Used to create and initialize properties of newly created objects
// Use the modulus operator to determine whether
// the array's length is odd or even
// Use Math.floor to truncate numbers
// Use Math.round to round numbers
if ((list_len % 2) == 1)
return list[Math.floor(list_len / 2)];
else
return Math.round((list[list_len / 2 - 1] +
2]) / 2);
} // end of function median
function plane(newMake, newModel, newYear){
this.make = newMake;
this.model = newModel;
this.year = newYear;
}
myPlane = new plane("Cessna",
"Centurnian",
"1970");
list[list_len /
- Can also have method properties
// Test driver
var my_list_1 = [8, 3, 9, 1, 4, 7];
var my_list_2 = [10, -2, 0, 5, 3, 1, 7];
var med = median(my_list_1);
document.write("Median of [", my_list_1, "] is: ", med, "<br />");
med = median(my_list_2);
document.write("Median of [", my_list_2, "] is: ", med, "<br />");
function displayPlane() {
document.write("Make: ", this.make,"<br />");
document.write("Model: ", this.model, "<br />");
document.write("Year: ", this.year,"<br />");
}
- Now add the following to the constructor:
this.display = displayPlane;
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
41
42
search(pattern)
- JavaScript provides two ways to do pattern matching:
1. Using RegExp objects
2. Using methods on String objects
- Returns the position in the object string of the pattern (position is
relative to zero); returns -1 if it fails
- Both ways use the same type of regular expressions, which are based
on PERL
- Patterns sent as parameters to pattern-matching methods are delimited
with slashes: /RegExp/
var str = "Gluckenheimer";
var position = str.search(/n/);
/* position is now 6 */
- Character classes
- Simple patterns
- Two categories of characters in patterns:
a. normal characters (match themselves)
b. metacharacters (can have special meanings in patterns--do not
match themselves)
- Put a sequence of characters in brackets, and it defines a set of
characters, any one of which matches
[abcd]
- Dashes can be used to specify spans of characters in a class
[a-z]
\ | ( ) [ ] { } ^ $ * + ? .
- A metacharacter is treated as a normal character if it is backslashed
- period is a special metacharacter - it matches any character
except newline
© 2009 by Addison Wesley Longman, Inc.
© 2009 by Addison Wesley Longman, Inc.
4.12 Pattern Matching (continued)
4.12 Pattern Matching
Chapter 4
Chapter 4
- A caret at the left end of a class definition means the opposite
[^0-9]
43
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
44
4.12 Pattern Matching (continued)
4.12 Pattern Matching (continued)
- Character classes (continued)
- Character class abbreviations
Abbr. Equiv. Pattern Matches
\d
\D
\w
\W
\s
\S
[0-9]
[^0-9]
[A-Za-z_0-9]
[^A-Za-z_0-9]
[ \r\t\n\f]
[^ \r\t\n\f]
- Quantifiers (continued)
- Other quantifiers (just abbreviations for the most commonly
used quantifiers)
a digit
not a digit
a word character
not a word character
a whitespace character
not a whitespace character
- * means zero or more repetitions
e.g., \d* means zero or more digits
- Variables in patterns are interpolated
- + means one or more repetitions
e.g., \d+ means one or more digits
- Quantifiers
- Quantifiers in braces
- ? Means zero or one
e.g., \d? means zero or one digit
Quantifier Meaning
{n }
{m,}
{m, n}
Chapter 4
exactly n repetitions
at least m repetitions
at least m but not more than n repetitions
© 2009 by Addison Wesley Longman, Inc.
45
4.12 Pattern Matching (continued)
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
46
4.12 Pattern Matching (continued)
- Anchors
- Other Pattern Matching Methods of String
- The pattern can be forced to match only at the left end with ^; at the
end with $ e.g.,
/^Lee/ matches "Lee Ann" but not "Mary Lee Ann"
replace(pattern, string)
/Lee Ann$/ matches "Mary Lee Ann", but
not "Mary Lee Ann is nice"
- Finds a substring that matches the pattern and
replaces it with the string (g modifier can be used)
- The anchor operators (^ and $) do not match characters in the stringthey match positions, at the beginning or end
var str = "Some rabbits are rabid";
str.replace(/rab/g, "tim");
- Pattern modifiers
str is now "Some timbits are timid"
$1 and $2 are both set to "rab"
- The i modifier tells the matcher to ignore the case of letters
/oak/i matches "OAK" and "Oak"
- The x modifier tells the matcher to ignore whitespace in the
pattern (allows comments in patterns)
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
47
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
48
4.12 Pattern Matching (continued)
4.13 Debugging JavaScript
- IE7
match(pattern)
- Select Internet Options from the Tools menu
- The most general pattern-matching method
- Returns an array of results of the pattern-matching operation
- With the g modifier, it returns an array of the substrings that
matched
- Without the g modifier, first element of the returned array has
the matched substring, the other elements have the values of
$1, …
- Choose the Advanced tab
- Uncheck the Disable script debugging box
- Check the Display a notification about every
script error box
- Now, a script error causes a small window to be
opened with an explanation of the error
var str = "My 3 kings beat your 2 aces";
var matches = str.match(/[ab]/g);
- matches is set to ["b", "a", "a"]
- FX2
- Select Tools and Error Console
split(parameter)
- A small window appears to display script errors
- Remember to Clear the console after using an
error message – avoids confusion
"," and /,/ both work
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
49
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
50
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
52
" SHOW forms_check.js
function tst_phone_num(num) {
// Use a simple pattern to check the number of digits and the dash
var ok = num.search(/^\d{3}-\d{4}$/);
if (ok == 0)
return true;
else
return false;
}
// end of function tst_phone_num
// A script to test tst_phone_num
var tst = tst_phone_num("444-5432");
if (tst) document.write("444-5432 is a valid phone no <br />");
else document.write("Program error <br />");
tst = tst_phone_num("444-r432");
if (tst) document.write("Program error <br />");
else document.write("444-r432 is not a valid phone no <br />");
tst = tst_phone_num("44-1234");
if (tst)
document.write("Program error <br />");
else document.write("44-1234 is not a valid phone no <br /");
Chapter 4
© 2009 by Addison Wesley Longman, Inc.
51