Given by Tom Scavo,Geoffrey C. Fox at CPS616 Technologies of the Information Age on Spring Semester 98. Foils prepared 20 April 98
Outside Index
Summary of Material
Java vs. JavaScript |
Simple motivating examples |
Event handling and scripting |
Language features and syntax |
JavaScript object model |
Built-in objects and functions |
Cookies and security |
LiveConnect and LiveWire |
Outside Index Summary of Material
Tom Scavo and Geoffrey Fox |
Northeast Parallel Architectures Center |
Syracuse University |
111 College Place |
Syracuse, NY 13244-4100 |
http://www.npac.syr.edu/projects/tutorials/JavaScript/ |
http://www.npac.syr.edu/users/gcf/javascriptapril98/ |
Java vs. JavaScript |
Simple motivating examples |
Event handling and scripting |
Language features and syntax |
JavaScript object model |
Built-in objects and functions |
Cookies and security |
LiveConnect and LiveWire |
JavaScript (originally called LiveScript) is an interpreter for Web documents |
Client-side JavaScript facilitates rapid prototyping and is more responsive than CGI |
JavaScript is particularly useful for frameset documents and HTML forms |
Refs: JavaScript, The Definitive Guide by David Flanagan (2nd ed, O'Reilly, 1997); The JavaScript Bible by Danny Goodman (3rd ed, IDG, 1998) |
JavaScript 1.0 debuted in NN 2.0 (Feb 96) |
JavaScript 1.1 appeared in NN 3.0 |
NN 4.0 (aka Communicator) supports JavaScript 1.2 |
MSIE 3.0 introduced JScript 2.0, a subset of JavaScript 1.1 |
JScript 3.0 is supported in MSIE 4.0 |
Both JavaScript 1.2 and JScript 3.0 are ECMA-compliant [ECMA Standard 262] |
New features in JavaScript 1.2 (NN4.0):
|
New features in JScript 3.0 (MSIE4.0):
|
JScript documentation is scarce, however |
Sun's Java is fast becoming a broad industry standard |
Java is well designed and documented |
Java is object-oriented with (single) inheritance |
JavaScript is primarily supported by Netscape |
JavaScript has neither of these qualities |
JavaScript is object-based with no class structure |
Java applets are distinct from HTML |
Java is strongly typed with static (compile-time) binding |
Java bytecodes are interpreted (or "Just In Time" compiled) on the client |
JavaScript is tightly coupled with HTML |
JavaScript is loosely typed with dynamic (run-time) binding |
High-level JavaScript source code is interpreted on the client |
Typically, up to 106 C instructions may be executed in a few milliseconds |
A Java interpeter is roughly 50 times slower than C |
Java "Just-In-Time" compiler is roughly 2–8 times slower than C |
Perl is 500 times slower than C |
JavaScript is 5000 times slower than C |
A script is enclosed in a <SCRIPT> container: <SCRIPT LANGUAGE="JavaScript"> ... </SCRIPT> |
Scripts may be put in the <BODY> or the <HEAD>, depending on your needs |
Use <NOSCRIPT>...</NOSCRIPT> for JavaScript-disabled browsers |
<HTML> |
<HEAD><TITLE>An Example</TITLE></HEAD> |
<BODY> |
<!-- Insert HTML here --> |
<SCRIPT LANGUAGE="JavaScript"> |
document.writeln("<H1>Hello World!</H1>"); |
</SCRIPT> |
<!-- Insert more HTML here --> |
</BODY> |
</HTML> |
There is only one JavaScript statement: document.writeln("<H1>Hello World!</H1>"); |
The writeln method writes its argument into the current document |
The script is in the <BODY> since it writes HTML code into the document; other scripts are written in the <HEAD> |
Scripts may be hidden from old browsers |
<HTML> |
<HEAD><TITLE>JavaScript with Forms</TITLE> |
<SCRIPT LANGUAGE="JavaScript"> |
function compute() { |
if ( window.confirm("Is this what you want?") ) |
aForm.result.value = eval(aForm.expr.value); |
} |
</SCRIPT></HEAD> |
<BODY><FORM NAME="aForm"> Enter expression: |
<INPUT TYPE="text" NAME="expr" SIZE=15> |
<INPUT TYPE="button" VALUE="Compute!" |
onClick="compute()"> <BR> Result: |
<INPUT TYPE="text" NAME="result" SIZE=15> |
</FORM></BODY> |
</HTML> |
confirm is a method of the Window object |
eval is a built-in JavaScript function (in NN2) |
onClick is a JavaScript event handler |
Note the user-defined names (aForm, expr, result) referred to in the script |
Events are associated with
|
JavaScript introduces event handlers to handle these events |
JavaScript 1.2 adds ten new event handlers |
Three existing handlers (onClick, onMouseOut, and onMouseOver) have new properties |
All these events are supported by IE4.0 except onDragDrop |
The onLoad event handler is triggered when a page is loaded or reloaded : <BODY onLoad="aFunction()"> The onUnload handler is called when a page is exited |
Here's another example: |
<FORM |
onSubmit="return check(this)"> |
... |
</FORM> |
A trivial example of a JavaScript URL is javascript:alert("Hello World!") |
A JavaScript URL may appear anywhere an ordinary URL is expected: <A HREF="javascript:history.back()">Previous Page</A> |
Navigator even has a mini-scripting environment invoked by typing javascript: into the browser's location text field |
If you have two versions of a JavaScript script, you can load one or the other: |
<SCRIPT LANGUAGE="JavaScript1.1"> |
// Ignored by Navigator 2.0: |
location.replace("newVersion.html"); |
</SCRIPT> |
<SCRIPT LANGUAGE="JavaScript"> |
// Read by Navigator 2.0 and above |
</SCRIPT> |
JavaScript code may be stored in an external file: |
<SCRIPT SRC="JScode.js"> |
// The body of this <SCRIPT> is |
// executed only if "JScode.js" |
// is not found! |
document.write("File not found!"); |
</SCRIPT> |
An external file must have a .js extension and the server must be configured properly |
JavaScript syntax resembles Java and C |
Braces { } are used for grouping |
Use single or double quotes (they are equivalent) around strings |
Literals: null, true, and false |
JavaScript is case-sensitive while HTML is not (which sometimes leads to problems!) |
Variables (identifiers) must begin with a letter, underscore, or dollar sign:
|
Declare variables in var statements: var aNumber = 137; var aString = "1"; |
Embed variables in HTML attributes: <IMG SRC="&{v1};" WIDTH="&{v2};"> where v1 and v2 are JavaScript vars |
Assignment operators: = += -= *= /= %= <<= >>= >>>= &= ^= |= |
Supports the usual arithmetic operators and %, ++, and -- |
Concatenation operator: + |
Bit operators: & | ^ ~ << >> >>> |
Relational operators: == > >= < <= != |
Logical operators: && || ! |
Examples:
|
An if-expression returns a value:
|
JavaScript statements include: break, continue, do, for, function, if, return, switch, var, while, and with |
Multiple statements on one line are separated by semicolons |
Statement blocks are delimited by braces |
Comments come in two flavors: /* any text including newlines */ // comment terminated by newline |
Assuming boolean variable isWhite: |
if ( isWhite ) { |
document.bgColor = "pink"; |
isWhite = false; |
} else { |
document.bgColor = "white"; |
isWhite = true; |
} |
The else block is optional, of course |
The switch statement is new is JS 1.2: switch ( fruit ) { case "oranges": price = 0.59; break; case "apples": price = 0.32; break; case "bananas": price = 0.48; break; default: price = null; } |
A simple for-loop: |
// Compute x^k for k > 0: |
for (var y=1, i=0; i<k; i++) { |
y *= x; |
} |
Here is another type of for-loop: |
for (var prop in object) { |
statements |
} |
A more general looping structure: |
// Compute r = m % n for m,n > 0: |
var r = m; |
while ( r >= n ) { |
r -= n; |
} |
break, labeled break, and continue are permitted in for and while loops |
JavaScript supports recursion as well |
A do...while loop tests its condition at the bottom of the loop: do { statements } while ( condition ); |
In this case, the loop body is executed at least one time |
This loop is new in JavaScript 1.2 |
with ( someObject ) { statements } |
someObject is the default object used for any unqualified object references: with ( Math ) { area = PI*r*r; // Math property PI x = r*cos(theta); // Math method cos y = r*sin(theta); // Math method sin } |
JavaScript is object-based with no classes and, hence, no inheritance |
An object possesses properties as well as methods |
A property is an attribute of an object |
A method acts on an object |
All JavaScript objects have eval, toString, and valueOf methods |
A fully-qualified reference: window.document.myForm.myButton.value |
window (often suppressed) and document are built-in object instances |
myForm and myButton are user-supplied object names |
value is a property of the Button object (and most other form elements) |
A Window object--the top-level JavaScript object--is the reflection of a <BODY> or <FRAMESET> tag |
A browser window may be divided into subwindows called frames |
A Frame object--the reflection of a <FRAME> tag--"inherits" all of its properties and methods from the Window object |
window and self are synonyms for the current window |
top refers to the highest-level window in a hierarchy of frames |
parent refers to the previous window or frame in a hierarchy of frames |
A window may have a name: myWin = window.open(URL); |
Note: The opener property is not supported in NN2. |
An analogy with the UNIX shell: |
A Frame object also has properties called window, self, and parent |
The most important property of the Frame object is the frames[] array |
Each <FRAME> tag automatically creates an entry in the frames[] array |
Frames may also have names, as in <FRAME NAME="upperFrame"> |
<!-- File: index.html --> |
<HTML> |
<FRAMESET ROWS="90%,10%"> |
<FRAME SRC="skeleton.html" |
NAME="upperFrame"> |
<FRAME SRC="navigate.html" |
NAME="navigateFrame"> |
</FRAMESET> |
<NOFRAMES>...</NOFRAMES> |
</HTML> |
<!-- File: skeleton.html --> |
<HTML> |
<FRAMESET ROWS="30%,70%"> |
<FRAME SRC="category.html" |
NAME="listFrame"> |
<FRAME SRC="titles.html" |
NAME="contentFrame"> |
</FRAMESET> |
</HTML> |
Absolute references:
|
Relative references:
|
In which documents are |
these references valid? |
The <FRAMESET> and <BODY> tags are mutually exclusive |
No closing tag for <FRAME> is needed |
A frameset document may contain a <SCRIPT> in its <HEAD> |
Use <NOFRAMES> inside <FRAMESET> for frames-impaired browsers |
Both Window and Frame objects have blur, focus, clearTimeout, and setTimeout methods |
The Window object also has alert, close, confirm, open, and prompt methods. For example, var msg = "The alert() method\n"; msg += " is handy for debugging."; window.alert( msg ); |
There is one History (and Location) object per window or frame |
The History object is essentially an array of URLs (called history[]), which most browsers restrict access to |
Two methods back() and forward() perform the same functions as the corresponding Navigator buttons |
The Location object corresponds to the URL of the current document |
To load a new document into the current window, use: window.location.href = "foo.html"; or simply window.location = "foo.html"; |
Location object properties: href, protocol, host, pathname, search |
There is one Document object (called document) per window or frame |
Document has numerous subobjects (Anchor, Applet, Embed, Area, Form, Image, Link, Layer) and property arrays (anchors[], applets[], embeds[], forms[], images[], links[], layers[]) |
A Document object has the following color properties: alinkColor, linkColor, vlinkColor, bgColor, and fgColor |
Other Document properties include lastModified and URL: with ( document ) { writeln('<TT>', URL, '</TT><BR>'); writeln('Updated: ', lastModified); } |
To list the properties of document: |
for ( var prop in document ) { |
with ( document ) { |
write(prop + " = "); |
writeln(eval(prop), "<BR>"); |
} |
} |
Recall that the with statement qualifies all object references within its scope |
The write(...) and writeln(...) methods take a comma-separated list of string expressions |
The open() and close() methods (not to be confused with window.open() and window.close()) open and close a document for writing, but these are seldom used explicitly |
Every Form object is the reflection of an HTML <FORM> tag |
The forms[] array may be indexed by integer or name (i.e., forms[0] or forms['myForm'] ) |
A Form object has many subobjects, each corresponding to an HTML form element. These are reflected in the elements[] array |
Form elements are reflected in the elements[] array. For example, document.forms[0].elements[1]; is the second element of the first form |
Most Form properties (action, encoding, method, and target) are read/write variables, that is, these properties may be modified on-the-fly |
Invoking the submit() or reset() method on a Form object has the same effect as pressing the corresponding button |
The event handlers onSubmit and onReset may be used to override the default submit and reset actions |
Think of a Layer object (new in JS 1.2) as a dynamic document within a document |
Each <LAYER> tag generates a Layer object and a corresponding element in the layers[] array |
Layers have many methods and properties (most of which may be modified on-the-fly) |
The Navigator object contains information about the browser |
Two properties are appName and appVersion |
Methods include javaEnabled and taintEnabled |
All windows share the same Navigator object, which is truly global |
The MimeType object is a subobject of the Navigator object |
The mimeTypes[] array contains an entry for each MIME type supported by the browser |
Properties of MimeType include description, type, and suffixes |
The property enabledPlugin refers to a Plugin object |
Like MimeType, the Plugin object is a subobject of the Navigator object |
The plugins[] array contains an entry for each installed plugin |
Each Plugin object is an array of MimeType objects. For example, navigator.plugins[0][0].type is a MIME type supported by plugins[0] |
JavaScript has ten built-in objects: |
plus a Math object (with no constructor) |
An instance object is created with new:
|
In NN 3.0 (and also in 2.0!), write: var states = new Array(50); states[0] = "Alabama"; states[1] = "Alaska"; // etc. |
Every array has a length property: n = states.length; // n = 2 |
Two-dimensional arrays are allowed: var acodes = new Array(50); acodes[0] = new Array(205,334); |
JavaScript 1.1 supports some powerful array methods:
|
Built-in Arrays |
JavaScript has numerous built-in arrays, each with its own length property: |
Plus the history array--the only one whose name does not end in "s"! |
Plus the elements array, whose parent is the Form object |
To create a false Boolean object, use: new Boolean() new Boolean(0) new Boolean(null) new Boolean("") new Boolean(false) or simply use the literal false |
All other values create a Boolean object with initial value true! |
The Date constructor has many forms: today = new Date(); xmas = new Date(97, 12, 25); birthday = new Date("April 6, 1952"); |
The Date() constructor may also be used as a function with no arguments |
Note: The Date object is buggy in NN2 |
The Date object has no properties; access to date and time fields is via numerous "set" and "get" methods: xmas.setYear(xmas.getYear()+1); |
There are two "static" Date methods:
|
Both convert their argument(s) to milliseconds past January 1, 1970 GMT |
Every function statement gives rise to a Function object |
Function objects are also created with the new operator: window.onload = new Function( "document.bgColor='white'"); |
Function objects may be anonymous |
Functions may take an arbitary number of arguments: function User() { this.name = User.arguments[0]; this.group = User.arguments[1]; this.email = new Array(); n = User.arguments.length; for (var i = 2; i < n; i++) this.email[i-2]=User.arguments[i]; } |
Note: the arguments[] array is built in |
Images may be pre-loaded; they should be cached in the <HEAD>, especially if they are to be used in the <BODY>: images = new Array( num ); for ( var i = 0; i < num; i++ ) { images[i] = new Image(); images[i].src = "image"+ i +".gif"; } |
This code loads files "image1.gif", "image2.gif", and so on |
Now suppose we have the tag <IMG NAME=img> in the <BODY>. The following recursive method animates the cached images: var n = 0; function animate() { document.img.src = images[n].src; n = (n + 1) % images.length; id = setTimeout("animate()", 250); } |
Math is the only built-in object that does not have a constructor |
Its sole purpose is to provide constants (properties) and functions (methods) |
The with statement is particularly useful in conjunction with Math: with (Math) { x = r*cos( PI/2 ); y = r*sin( PI/2 ); } |
These properties are primarily for convenience: |
Each method in the middle column requires two args |
There is a Number constructor, but it is rarely used since JavaScript automatically converts numeric literals to numeric objects when necessary |
Some useful properties are provided, however: MAX_VALUE, MIN_VALUE, NaN, NEGATIVE_INFINITY, and POSITIVE_INFINITY |
Number.MIN_VALUE is the smallest positive number representable |
Number.POSITIVE_INFINITY is returned by any operation that is greater than Number.MAX_VALUE |
Number.NEGATIVE_INFINITY is returned by any operation that is less than -Number.MAX_VALUE |
Number.NaN is returned by parseInt() and parseFloat() when the parsing operation fails |
An attempt to divide by zero also returns Number.NaN |
Test for Number.NaN using the boolean function isNaN() |
Note: NN2.0 and MSIE3.0 do not support Number.NaN! |
The Object constructor converts its argument (any numeric, boolean, or string literal) to a JavaScript object: var s = new Object( "NPAC" ); is equivalent to var s = new String( "NPAC" ); This is usually unnecessary, however |
String objects are created as in var myStr = new String("NPAC"); or more simply with var myStr = "NPAC"; |
Actually, the latter is a string literal, but these are automatically converted to objects when necessary |
String characters are indexed starting with 0 |
The String object has one property: var n = myStr.length; |
There are two groups of methods:
|
Six new methods added in JavaScript 1.2 |
An Event object (new in JavaScript 1.2) is passed to an event handler when an event occurs |
There are 23 types of events, one for each handler: for example, a Click event is passed to the onClick handler when a link or form element is clicked |
An Event object has up to 11 properties |
Properties of an Event object: |
The Click object, for example, supports all but the data property (although the *X and *Y properties are undefined for button clicks) |
An RegExp object (new in JavaScript 1.2) corresponds to a regular expression |
There are two syntaxes: regexp1 = new RegExp( "pattern" ); regexp2 = /pattern/; |
The latter "compiles" the pattern: regexp2 == regexp1.compile("pattern") |
The RegExp object has two other methods: exec( str ) and test( str ) |
Here are some examples: function isDigit( str ) { var regexp = /^[0-9]*$/; return regexp.test( str ); } function isSSN( str ) { // match 999999999 or 999-99-9999 var regexp = /^(\d{9}|\d{3}-\d{2}-\d{4})$/; return regexp.test( str ); } |
String methods have been added to JavaScript 1.2 to handle regular expressions: search( regexp ); // like test(...) match( regexp ); // like exec(...) replace( regexp, newsubstr ); |
match(...) returns an array of strings |
The split(...) method now takes a regular expression as optional parameter: var strArray = str.split( /\s*;\s*/ ); |
Objects are defined with the function statement. The following Circle object, for example, has property r: function Circle( r ) { this.r = r || 1.0; } |
The this keyword permits this function to be used as a constructor: var c = new Circle( 2.0 ); var area = Math.PI * c.r * c.r; |
User-defined Methods |
Methods are defined as Function objects: function Circle( r ) { this.r = r || 1.0; this.getRadius = new Function( "return this.r" ); this.setRadius = new Function( "r", "this.r = r" ); } |
Note: The last argument of the Function constructor is implicitly the method body |
Methods may be added after the fact: function Circle_area() { return Math.PI * this.r * this.r; } Circle.prototype.area = Circle_area; |
Use the previous method as follows: var radius = 1/Math.sqrt( Math.PI ); var c = new Circle( radius ); var area = c.area(); |
Add methods to built-in objects: // Does an array contain element x ? function contains( x ) { for (var i=0; i<this.length; i++) { if (this[i] == x) return true; } return false; } |
Add the method to the Array object with the prototype property: Array.prototype.contains = contains; |
Here's another example: function Car( make, model ) { this.make = make || ""; this.model = model || ""; this.color = null; this.setColor = new Function( "color", "this.color = color" ); } |
Instantiate a Car object with new: myCar = new Car( "Ford", "Explorer" ); myCar.setColor( "red" ); |
Built-in Functions |
JavaScript has seven built-in functions not associated with any object: |
Plus the boolean function isNaN(), which is used in conjunction with the parsing functions |
parseInt() and parseFloat() convert their arguments to numbers: parseFloat("12.34"); //returns 12.34 parseInt("12.34"); //returns 12 parseFloat("12.34 ft"); //returns 12.34 parseInt("111", 2); //returns 7 parseFloat("$12.34"); //returns NaN |
A handy trick: var numeric_val = string_val - 0; |
The function eval(str) evaluates its string argument in the context of the current window |
In NN3.0 and later, eval(...) may be invoked on an arbitrary object (i.e., eval is a genuine method); in this case, its argument is evaluated in the context of that object |
A cookie is:
|
The cookie mechanism gives the browser a kind of memory, that is, a cookie "saves state" |
Originally, only CGI scripts could read/write cookie strings, but with JavaScript, cookies are handled entirely on the client side |
A cookie
|
A cookie string may not contain semicolons, commas, or whitespace (use escape() and unescape()) |
Minimum specifications:
|
When browsing the Web, two pieces of information are considered public: the IP address of the client and the type of browser. All other data are considered private. In particular,
|
An important bug fix appeared in NN2:
|
http://www.osf.org/~loverso/javascript/ |
For example, a script from home.netscape.com may not read the properties of a document loaded from developer.netscape.com |
The document.domain property is initialized to the hostname of the server from which the document was loaded |
This property may be set to any valid domain suffix of itself |
For example, if document.domain is "home.netscape.com", it may be set to "netscape.com" (but not "ape.com") |
Data tainting, an alternative to the Same Origin Policy, was experimentally implemented in NN3.0 |
Data tainting allows access to private data (e.g., history[] array) but forbids "export" of this data over the Internet |
Both data and methods may be tainted |
Tainting has been disabled in NN4, in favor of signed scripts |
A new security model called signed scripts was implemented in NN4.0 |
Signed scripts are based upon the Java security model for signed objects, and include the following:
|
Scripts are signed using Netscape's Page Signer tool (a Perl script) |
Scripts may be served from a secure (SSL) server, in which case they're treated as if signed with the public key of that server |
Users retain the right to deny the privileges requested by the signed script |
LiveConnect is a communications protocol for Java applets, plugins, and JavaScript |
A JavaObject is a JavaScript wrapper around a Java object; a JSObject is a Java wrapper around a JavaScript object |
MSIE3.0 does not support LiveConnect; instead, applets are treated as ActiveX objects, but the basic syntax is the same |
With LiveConnect:
|
LiveWire is a non-standard alternative to CGI |
LiveWire lets developers write CGI programs in JavaScript |
It consists of two components: a compiler and a server extension |