New JavaScript Features in Atlas PR2

NOTE: This is preliminary documentation of new JavaScript features in the current Navigator beta (Atlas PR2), provided for the benefit of the developer community. In the future, these sections will be improved and integrated in the body of the JavaScript Guide.

Summary

Language features

Navigator JavaScript features


Language Features

These are new features of the JavaScript language itself, and will ultimately apply to both client and server JavaScript. (Note: these JavaScript features are not in the current LiveWire beta)

Arrays

There is now a special object type, called Array, that you can define instances of with the new operator. Once you have an array, you can assign values to its elements, just as you would any variable. For example,

    var a = new Array()
    a[0] = "hi"
    a[99] = "world"
    if (a.length == 100)	// This is true, because defined a[99] element.
       document.write("The length is 100")
You can define an initial length when you create the array, if you want to define a size for the array, but you don't want to bother with defining a[99] = null just to get the length to be 100:
    var a = new Array(100)

You can't set the length property explicitly by assignment. However, as shown in the above examples, you can set length by an explicit argument to a constructor, or implicitly by setting an indexed property where the index is greater than or equal to the previous length value.

Finally, if you want to construct a "dense" array of two or more elements starting with index 0, and you have initial values for these elements, you can call the Array constructor with arguments for the element values. (A dense array is one in which each element has a value.) For example,

    var a = new Array("foo", bar, 3.14159)

The typeof operator

The typeof operator returns a string telling the type of its unevaluated operand. For example,

    typeof foo == "undefined"	// where foo is undefined
    typeof eval == "function"
    typeof null == "object"
    typeof 3.14 == "number"
    typeof true == "boolean"
    typeof "a string" == "string"

String object features

String objects are now "real" objects. You normally construct strings literally by quoting some characters, and if you want to use them as objects, you follow a string reference with .length or .indexOf("sub"), as if it were an object. Now, you can make string objects using new:

    var s = new String("hello")

These strings are reference-counted and may be passed among scripts in different windows or frames without any "weak link" corruption problems that affected Navigator 2.0, and which required the workaround of adding the empty string to another window's string to "import" it:

    var mys = otherWindow.s + ""    // 2.x: import other window's string
    var mys = otherWindow.s         // 3.x: ok, strong link works

Object prototypes

JavaScript now explicitly allows you to extend all objects after you create them with the new operator. This applies to built-in constructors such as Date and String, as well as user-defined object types.

Set the value of objType.prototype.propName to define a property that is shared by all objects of the specified type, where objType is the object type (the name of the constructor function) and propName is the name of the property.

    var s1 = new String("a"), s2 = new String("b")

    // add a repeat-string-N-times method to all strings:
    function str_rep(n) {
        var s = "", t = this.toString()
        while (--n >= 0) s += t
        return s
    }

   String.prototype.rep = str_rep    // add a rep() method to String

    s1.rep(3) == "aaa"
    s2.rep(5) == "bbbbb"

    var s3 = new String("c")
    s3.rep(2) == "cc"

    function fake_rep(n) { return "repeat " + this + " n times." }
    s1.rep = fake_rep
    s1.rep(1) == "repeat a 1 times."

    s2.rep(4) == "bbbb"		// still works!
    s3.rep(6) == "cccccc"

This works with user-defined objects too:

function Car(make, model, year) {
    this.make = make
    this.model = model
    this.year = year
}

Car.prototype.wheels = 4        // no 3-wheelers please!

var mine = new Car("Acura", "Integra", 1987)

if (mine.wheels == 4)        // true!
   document.write("Car has ", mine.wheels, " wheels.")

Indexing object properties

When you define an object's properties with property names, you cannot refer to these properties by their ordinal index, as you could in Navigator 2.0. This applies when you create an object and its properties with a constructor function, as in the above example of the Car object type, and when you define individual properties explicity (for example, myCar.color = "red").

If you define object properties initially with an index, for example,

myCar[5] = "25 mpg"
then you can subsequently refer to the property as myCar[5].

The rule is: if you initially define a property by its name, you must always refer to it by its name. If you initially define a property by an index, you must always refer to it by its index.

The exception to this rule is objects reflected from HTML: for example, the frames, forms, elements, and anchors arrays. You can always refer to these objects by their ordinal number (based on where they appear in the document) and by their name (if defined). For example, you can refer to the second form in a document as document.forms[1] or as document.myform, if the second FORM tag has a NAME attribute of "myform".

Random number function

The Math.random() method now works on all platforms. The random number generator is seeded from current time, as in Java.


Navigator JavaScript features

These are new or improved features of client JavaScript.

Image reflection and event handlers

Images defined by the IMG tag are now reflected in JavaScript. All images in a document are in an array called document.images, and the number of images in a document is document.images.length. So, for example, you refer to the first image in a document as document.images[0], the second image as document.images[1], and so on.

Each image object has properties for the IMG attributes:
Property Name Reflection of
src SRC attribute: URL of the image file. This is the only required attribute.
lowsrc LOWSRC attribute: URL of the low-resolution image file.
height, width HEIGHT, WIDTH attributes: height and width of image in pixels (read-only).
border BORDER attribute: width of image border in pixels (read-only).
vspace, hspace VSPACE, HSPACE attributes: horizontal and vertical space in pixels (read-only).
complete Boolean value that indicates whether Navigator has completed its atttempt to load the image (read-only).

The position and size of an image in a document are set when the document is displayed in Navigator. However, you can set the src and lowsrc properties to change the image displayed.

Setting the src attribute has the side-effect of actually starting to load the new URL into the image area (and aborting the transfer of any image data that is already loading into the same area). Therefore, if you're going to alter the lowsrc property, you need to do so before setting the src property. If the URL in the src property references an image that is not the same size as the image cell it is loaded into, the source image is scaled to fit.

There are three event-handlers for images:

The onload event handler indicates the script to execute when the image is displayed. In particular, GIF animation allows programmed delays to be inserted between indiviual frames, so data transfer may complete before the last frames in the animation are drawn. Also, GIF animations that are looped (repeating) will trigger an onload event every time the animation completes.

Form element type property

All form elements have a type property reflected from the INPUT tag's TYPE attribute, or given a name based on the tag name for form elements specified by other tags:
HTML element Value of type property
INPUT TYPE=text "text"
INPUT TYPE=radio "radio"
INPUT TYPE=checkbox "checkbox"
INPUT TYPE=hidden "hidden"
INPUT TYPE=submit "submit"
INPUT TYPE=reset "reset"
INPUT TYPE=password "password"
INPUT TYPE=button "button"
SELECT "select-one"
SELECT MULTIPLE "select-multiple"
TEXTAREA "textarea"
INPUT TYPE=image "image"
INPUT TYPE=file "file"

Window focus and blur

The focus and blur methods now apply to windows. The focus method gives focus to a window, which brings it forward in most windowing systems. The blur method removes focus from the window, which sends it to the background in most windowing systems.

Cancelling onClick

The onclick event handler can return false to cancel the action normally associated with a click event. For example, click the following hyperlink and then chose "Cancel". Netscape

If you click "Cancel" the new page will not be loaded. This behavior is the same for all onClick event handlers.

Window opener property

Windows opened or created by executing open method have an opener property that refers to the window containing the document that called open. This property persists across document unload in the opened window.

So you no longer have to set a "creator" or "owner" property by hand, you can use the predefined one. Backward compatible code:

    var w = window.open()
    if (w != null && w.opener == null)
        w.opener = window

Calling event handlers explicitly

You can now reset an event handler specified by HTML from within JavaScript, for example:

<SCRIPT LANGUAGE="JavaScript"> function fun1() { ... } function fun2() { ... } </SCRIPT> <FORM NAME="myForm"> <INPUT TYPE=button NAME="myButton" onClick="fun1()"> </FORM> <SCRIPT> document.myForm.myButton.onclick = fun2 </SCRIPT>

Note that event handlers are function references, so you must assign fun2, not fun2() (the latter calls fun2 and has whatever type and value fun2 returns).

Also, since the event handler HTML attributes are literal function bodies, you cannot use <INPUT onClick=fun1> in the HTML source to make fun1 the onClick handler for an input; you must call fun1 instead, as in the example.

Finally, because HTML is case-insensitive while JavaScript is case-sensitive, you must spell event handler names in JavaScript in lowercase.

Modifiable select objects

The popup menus and list boxes reflected from the SELECT tag can now be modified to have different options from those specified via HTML.

There are two basic techniques:

Use the first technique to select multiple items for selection elements with the MULTIPLE attribute.

You can also set option.text directly. For example, suppose you have a form with the following Select object:

<SELECT name="userChoice"> <OPTION>Choice 1 <OPTION>Choice 2 <OPTION>Choice 3 </SELECT>

Then you can set the text of the ith item in the Selection based on text entered in the text field named textField as follows:

myform.userChoice.options[i].text = myform.textField.value;

NOTE: TIn the current release, you must use parseInt(i, 10) instead of simply i as the argument to the options array above.

For example, enter some text in the first text field below and then enter a number between 0 and 2 (inclusive) in the second text field. When you click on the button, the text will be substituted for the indicated option number.


Text to change to:
Item number to change: