[Skip Navigation] [CSUSB] / [CNS] / [CSE] / [R J Botting] / [Samples] / javascript
[Index] [Contents] [Source Text] [About] [Notation] [Copyright] [Comment/Contact] [Search ]
Wed Feb 27 10:51:56 PST 2013




      JavaScript is a rapidly evolving family of similar languages with a complex history. It was designed to make HTML pages more dynamic by (1) allowing the page to be computed rather retrieved from a file, (2) allowing executable subprograms to be associated with events occurring in a browser, and (3) allowing programs to be executed on a server that generates pages.

      See JavaScript_introduction for a good and easy to read introduction.

      JavaScript is an interpreted object_based, statically_scoped, and dynamically_typed language. It has no local constants. All variables and functions(subprograms) are properties (attributes) of some object. Some of these are read only. It has automatic garbage collection.

      (object_based): JavaScript uses the prototype model of objects (a class of objects share a common prototype object) rather than a statically declared class hierarchy. As of 1999 there is no portable way to set up such a complex hierarchy. Each object inherits from its prototype object and the prototype object inherits from a global Object object. A property that is set up in the prototype becomes a default property of the object.

      Functions are objects and yet also play part rather like classes in other languages:

      (statically_scoped): The scope of an identifier is determined before executing the code. JavaScript has two kinds of scope: global and local. Global variables are shared by the whole program. Local variables have a complete function as a scope. In later JavaScripts functions can be declared inside functions creating nested scopes.

      (dynamically_typed): The type assigned to a variable is determined by its current value. There is an operator typeof that can determine the type of a value. There are half-a-dozen different types -- see Types for a list. All objects are of type "object". All functions are of type "function". There is no concept of type being based on a class because the language is object_based and has no classes in the Java/C++/Smalltalk sense.

    1. history::=LiveScript; JavaScript1.0; JavaScript1.1; JavaScript1.2; Javascript1.3; ...
    2. JScript::=JScript1.0; JScript1.2.
    3. |-Jscript1.0 = MS(JavaScript1.0), -- Microsoft's implementation of JavaScript.
    4. |-Jscript1.2 = MS(JavaScript1.2).
    5. ECMAScript::=A sequence of developing standard definition, standard ECMA-262 = standard ISO-10262.
    6. |-ECMAScript roughly_equal_to JavaScript1.1.

      Netscape 4 was released when Javascript1.2 and ECMAScript drifted badly apart. As a result some features have a special effect only when Netscape 4 is used and JavaScript1.2 is specified as the language in the SCRIPT tag.


      In my opinion (based on 30 years of programming and about two dozen different languages) the existence of multiple versions and incompatible implementations means it is immature and risky to use. Because it is dynamically_typed it is easy to experiment with simple programs. It is also inexpensive but slow to run. The absence of a static class hierarchy, information hiding, and other advanced features will make large scale projects difficult. These features combine to make it unready for engineering reliable software. I expect it to become the Street BASIC of the future.

      2010 -- I can now add to the above comment that JavaScript strings and user input make the language highly insecure.

      These notes will focus on the one case where it is difficult to avoid JavaScript. Only the simplest and most stable parts will be covered. These notes are on the parts of JavaScript that can be used to generate and animate pages in a browser. This is sometimes called "client-side" JavaScript.

      Simple Example

      The following instructs a browser to find the current date and time and write it into the page as it is loaded:-
          <HTML> <HEAD> <TITLE>Dynamic Schedule</TITLE>
          <SCRIPT language=JavaScript>
            var now=new Date();
            document.write("The Time is "+now);
          // --->
      The user gets a page from the browser that has a line starting "The Time is " and finishing with the date and time.

      Essential HTML

        This section gives some ways for embedding JavaScript in the HyperText Mark Language(HTML).


      1. script_inside_HTML::= script_tag # statement "</SCRIPT>". Note.
        1. The string </SCRIPT> must be avoided inside the statements above!
        2. There can be many SCRIPTs in one page and they are all part of the same program.

      2. script_tag::="<SCRIPT " O(language_attribute) O(source_attribute) ... ">"
      3. language_attribute::="LANGUAGE=" double_quote "JavaScript" Oversion double_quote.
      4. version::= "1.0" | "1.1" | "1.2" .
      5. source_attribute::= "SRC" "=" double_quote file_path_name double_quote, as long as the server can handle MIME-type "application/x-JavaScript" for files with suffix or extension ".js".

        JavaScript URLs

        In stead of specifying a protocol (like "ftp" or "http") an Universal Resource Locator or URL can be the string "javascript". So in an <A HREF="..."> tag or a FORM tag can refer to a javascript statement to be executed rather to a location on the WWW:
                 <A HREF="javascript: ... ">...</A>
                 <FORM ACTION="javascript: ... ">.... </FORM>

        Later Features

          1. These features are evolving.
          2. They may be different for MS browsers.

          Event Handlers

                   <A HREF="...." onClick="....">
        1. event_handling_attribute::= event_name "=" double_quote #statement double_quote.
        2. event_name::= "on" event_type.
        3. event_type::=event_type0 | event_type1 | event_type2, these are for version 1.0, 1.1, and 1.2 respectively.
        4. event_type0::= "Blur" | "Change" | "Click" | "Focus" | "Load" | "MouseOver" | "Unload".
        5. event_type1::= "Abort" | "Error" | "MouseOut" | "Reset" | "Submit".
        6. event_type2::= "KeyDown" | "KeyPress" | "KeyUp" | "MouseDown" | "MouseUp" | "Resize" | variant_event_type. variant event types depend on the browser and/or the platform
        7. variant_event_type::="DblClick" |...

          JavaScript generate SGML entities

                   &( statements );

          Style Sheets

        8. style::= style_tag # statement "</STYLE".
        9. style_tag::= "<STYLE" "TYPE=" double_quote "text/JavaScript" double_quote ">".

        . . . . . . . . . ( end of section Later HTML Features) <<Contents | End>>

      . . . . . . . . . ( end of section Essential HTML) <<Contents | End>>

      Essential Syntax

        JavaScript inherits and extends a lot of the syntax of the C Programming Language.


      1. identifier::= (("$" | "_" | letter )#(letter | "_"| digit ) ) ~ reserved.

      2. reserved::= keywords | ECMA_extensions | Java_keywords.

      3. keywords::= "break" | "case"|"do" | "continue" | "default" | "delete" | "else" | "export" | "for" | "function" | "if" | "import" | "in" | "new" |
      4. "return" | "switch" | "this" | "typeof" | "var" | "void" | "while" | "with" .
        1. break::lexeme, terminates a case or (perhaps) a loop.
        2. case::lexeme, used to state a case in a switch statement.
        3. do::lexeme, stars a do-while loop.
        4. continue::lexeme, goes to begining of next repetiton of loop.
        5. default::lexeme.
        6. delete::lexeme.
        7. else::lexeme, terminates the true branch of an if-else and starts the fale branch.
        8. export::lexeme.
        9. for::lexeme, states a C-style for-loop.
        10. function::lexeme, starts a function defintion.
        11. if::lexeme, starts an if-else selection statement.
        12. import::lexeme.
        13. in::lexeme.
        14. new::lexeme, indicates the creation and construction of an object using a function.
        15. return::lexeme, exit from a function.
        16. switch::lexeme, starts a switch selection statement as in C.
        17. this::lexeme, the object being constructed or to which a function is applied.
        18. typeof::lexeme, determines the current typ of a variable.
        19. var::lexeme, declares a new variable.
        20. void::lexeme, indicates a function that reurns no value.
        21. while::lexeme, starts a while loop.
        22. with::lexeme.

      5. comment::= CPP.comment, /*...*/ and //...end of line.

      6. literal::=C.literal | single_quoted_string | named_literal | function_literal |object_initializer | array_initializer | this.
        1. single_quoted_string::= "'" #non("'") "'". -- needed to allow "..." for HTML!
        2. Unicode_escape_sequence::= "\\u" hex hex hex.
        3. hex::= "0".."9" | "A".."F".
        4. named_literal::= "Infinity" | "NaN" | "null" | ... .
        5. object_initializer::= "{" List( identifier ":" literal ) "}".
        6. array_initializer::="[" List( literal ) "]". -- may be different types.
        7. function_literal::="function" "(" List(identifier) ")" "{" body "}".
        8. this::="this", -- current object.

        A sublanguage of JavaScript for describing literal objects forms the Java Object Notation [ JSON.html ] that is (2012) catching on for sharing data/objects between components.


      7. expression::=C.expression(TBA) | typeof_expression | constructor |... .

        JavaScript has all the operators of C plus a new shift operator ">>>". The "%" remainder operator can return negative remainders. The "+" operator is overloaded to concatenate strings as in BASIC.

      8. typeof_expression::= "typeof" unary_expression, see typeof.

      9. constructor::= "new" constructor_function "(" O List(expression)")".
                 new Date()
        The "new" creates a new "this" object. The constructor function initializes properties of the this object. It must not return an object. It initializes the properties of the new object. It also links the new object to a shared prototype object. If a function is used as a constructor (with "new" ) then it has extra properties: prototype, constructor, ... The functions prototype object can be given properties (including methods and functions) that are shared by all objects it constructs.

        There are a number of ready made constructor functions:

      10. predefined_constructor_functions::=following
        • Date() -- Date
        • Object() -- Object
        • Function( argument_strings, statement_string ) -- Function
        • Array(...) -- JavaScript1.1 and above, Array
        • RegExp(...) -- JavaScript1.2 and above, RegExp


         		"This is the time" + now
      11. length::string->number. For s:string, s.atChar(i) = s[i], -- ASCII, starting with atChar(0),
      12. s.atCharCode(i)=s[i], -- Unicode.
      13. s.substring(i,j)::=s(i..j), later substr is also allowed.
      14. s.indexOf(c)::= min{i | s(i)=c }.
      15. s.toUpperCase()::string.
      16. s.toLowerCase()::string. Notice: There is no operation to change parts of a string. Strings are immutable -- trying to change a character in a string creates a new string.

        JavaScript has many HTML specific operations on strings:

      17. anchor(name)::method, return string as text in <A HREF="name">this</A>.
      18. link(name)::method, is similar to anchor.
      19. big()::method, return string in between <BIG> ... </BIG>. blink, bold, fixed, italics, small, strike, sub, sup are similar.
      20. fontcolor(color)::method,
      21. fontsize(size)::method.

        Regular Expressions

        These were borrowed from Perl 4 and placed in JavaScript1.2. Perl borrowed them from various programs available since the 1970's in UNIX, which in turn got them from a Mathematician called Kleene in the 1940's[RE]!

        These are used to make editing (find and replace) operations on strings easy.

        A Regular Expression object is constructed like this

                 new RegExp( regular_expression )
      22. regular_expression::="/" pattern "/".
      23. pattern::= O(at_start) #( (wildcard | special | # normal_char ) O("*") ) O(at_end).
      24. at_start::="^".
      25. at_end::="$".
      26. wildcard::= "." | "[" char "-" char "]".


      27. math_function::= "Math".name.

      28. function_declaration::="function" identifier "(" O List(identifier) ")" "{" body "}".

      29. body::=# statement.

      30. function_call::= function_indicator "(" OList(expression) ")" .
      31. function_indicator::= function_literal | function_name | object #("." property ) "." method.


            object . property
            object . function ( arguments )


        The rules for statements are quite close to C but for the following:
      32. statement::= C.statement with following,


        The scope of a variable is determined by the function (if any) in which it occurs. Even if a variable is used before it is declared it is still a local variable. Even if it is declared in a for_statement or a compound statement its scope is still the whole function.

      . . . . . . . . . ( end of section Essential Syntax) <<Contents | End>>

      Essential Semantics


        There are half-a-dozen data types in JavaScript. Given an expression then the typeof function (in Netscape 3 and MS Explorer 3 and later) returns a string that is the name of one of these type:
      1. typeof::expression -> Types.
      2. Types::= { "object", "undefined", "number", "string", "boolean", "function" }. Arrays are of type "object".

        Values are either strings, primitive, or reference:

      3. primitive::=number | null | undefined | boolean.
      4. reference::=object | array | function.

        Each numbers, strings and booleans have an associated constructor functions that place them as a property of an object:

                 new Number(42)
                 new String("Slarty Bardfast")
                 new Boolean( b*b > 4.0*a*c )


        The equality operator "==" is intended to test for the equality of the values of two expressions. Inequality is the negation of this "!=". Nulls and undefined values are all equal. Normally values of different types are coerced to fit each other using mappings like:
      5. coercion::= number; string | true +> 1 | false +> 0 | object; toString.

        Exception: If the browser is Netscape 4 and the language of a script is specified like this

                 <SCRIPT LANGUAGE="JavaScript1.2>
        and then types are not coerced by "==".


        The "==" operators test for equality of two values having corced them to the same type, I guess. Newer JavaScripts have "===" and "!==" tests to see if the values of two expressions are identical without coercion. It also treats null and undefined as non-identical.

        Identity vs equality

        This link [ http://zero.milosz.ca/ ] gives a table of values of "==" and "===" for different arguments. Do not be surprised that
        is false!


        JavaScript has the usual C assignment operators. The precise meaning (copy value vs copy reference) depends on the type assigned. Primitive values are copied by value and references by reference. Strings form a special case in that they may assigned either way but there is no way to distinguish which occurred.

        There is one non-C assignment operator: ">>>=" which shifts bits to the least significant end of a value and introduces '0' rather than the sign of the value

        Creation and Deletion

        JavaScript has the "new" operator which constructs new objects and calls a function to initialize them. Later JavaScripts have an explicit "delete" operator.

        The Void Operator

        JavaScript introduces a new kind of operator that converts any value into an undefined one. It is symbolized "void". It is used when you need for some expression to be executed but don't want the value to be used or displayed. It can also be used in later JavaScripts with the "===" identity operator to test for a value of an expression being undefined.

        Arrays and Objects

        In JavaScript arrays are indexed collections of data of any type what so ever. They can be indexed by a number or by a string:
                 array [ index ]

        Objects have properties that can accessed in two ways:

                 object . property
                 object [ expression ]
        The expression above must return a string which is the name of a property. So Objects are also associative arrays (as in awk). It is possible, in a for loop, to make a variable visit every property in the object:
                 for( var p in object ) { .... object[p] ... }

        In earlier JavaScripts all arrays were Objects. As new properties were added to objects they were stored in an indexed array numbered [0], [1], ... In later JavaScripts Arrays have been separated from Objects and given a set of special functions and methods.


        Each function call creates a new execution context (global environment) that includes an explicit local activation record called the "call object". The different execution objects are themselves properties of a global object and can be referred to (TBA).

        When a function f is called with an object o like this

      6. o.f(parameters) then o is said to be the "call" object. It replaces the symbolic this variable used in the function declaration.

        Functions can be used as-if they where data. For example an object can have a new property defined that is set to a function. If, for example, an object o has function f assigned to property p:

                 o.p = f;
        calls f with this (the "call object") set to o. Functions can also be items in an array indexed by a number or a string.

      7. function_properties::={ this, "arguments", "prototype", ...}.
      8. arguments::array=an array of the values passed to a function by a call.
      9. prototype::Object, an object attached to a function that is shared by all objects that are created by the function which contains the default properties of the object.

      10. argument_properties::={ "caller", "callee", "length", "arity" }.

        Adding new properties to a function has the effect of creating what are called static variables in C and C++. The prototype property allows a function to be used to create objects that share common methods and attributes.

        Netscape 4 and above have two methods "apply()" and later ones may add "call()".


        The scope for variables in a Function constructor is always the global scope.

        To find the meaning of a variable(property) in a function declaration or literal first check the local variables in the function, then the properties of the function's prototype object. Then such in the function that declared the current function. and so on.

        Regular expressions however use dynamic scoping.

      . . . . . . . . . ( end of section Essential Semantics) <<Contents | End>>

      Essential Predefined Features

        The following list some common methods and properties of various predefined types and objects in JavaScript.
      1. method::=a function that is used together with an object: x.f(...).
      2. property::=a value attached to an object: x.p.
      3. function::=`a "free" function that is not used with an object but with a constructor function: Math.f(...)`.
      4. value::=a value associated with an function that constructs objects: Math.pi.
      5. event::=attribute that indicates a command to be executed when some event occurs.

        Useful Predefined functions

      6. eval(s)::function=evaluate string s. DANGER!
      7. isFinite(n)::function=true iff n is not infinite.
      8. isNaN(n)::function=true iff n is Not a Number.
      9. parseInt(s)::function,
      10. parseInt(s, radix)::function,
      11. parseFloat(s)::function,


        By default all new object have these features:
        1. toString()::method=returns a string representation of an object.
        2. toString(base)::method=expresses number in decimal, octal, hex, etc..
        3. valueOf()::method=returns a primitive value equivalent to the object, -- if there is such a value.


        An input element in a form looking like a push button. It has a name and value from HTML tags and has the onClick event.


        An input in a form looking like a check cox. It has a name and value from HTML tag and has the onClick event and boolean checked.


        Buggy in Netscape 2. Dates are held as numbers representing the number of milliseconds since midnight GMT Jan 1st 1970.

        It has several constructors: Date(), Date(string), Date(yy,mm,hh,mm,ss,ms), Date(ms).

        Date objects have a large number of attributes accessed by "set" and "get" methods:

      12. Date_method::= ("set" | "get" ) Date_attribute | "toGMTString" | "toString" | "toUTCString" | "valueOf".

      13. Date_attribute::= O("UTC") ("Date" | "Day" | "FullYear" | "Hours" | "Milliseconds" | "Minutes"| "Month" | "Seconds" )| "Time" | "TimezoneOffset" .
      14. Date.parse(s)::function = convert s to Date.
      15. Date.UTC::function=numeric time to Date.

        I say nothing about functions that use 2 digit years.


        A form has a name, a number of input and other elements and an action that is executed when a Submit button is selected.
      16. onReset::event, when a Reset button is selected is clicked.
      17. onSubmit::event, when submit button on form is clicked.


        Part of a Form allowing input. Examples: buttons, checkboxes,.... see input below.
      18. onClick::event.
      19. onChange::event.


        An HREF Anchor in HTML.
      20. onClick::event.
      21. onMouseOver::event.
      22. onMouseOut::event.


        See location.


          A collection of useful values and functions always shown as "Math."name.


          These are actually variable.... do not change them by accident.
        1. E::value,
        2. LN10::value,
        3. LN2::value,
        4. LOG10E::value,
        5. LOG2E::value,
        6. PI::value,
        7. SQRT1_2::value,
        8. SQRT2::value.


        9. min(x,y)::function,
        10. max(x,y)::function,
        11. abs(n)::function,
        12. ceil(x)::function,
        13. floor(x)::function,
        14. round(x)::function,
        15. random()::function=pseudo-random number in range 0.0 to 1.0.

          Powers etc

        16. sqrt(x)::function,
        17. pow(x,n)::function,
        18. exp(x)::function,
        19. sqrt(x)::function,
        20. log(x)::function,


        21. sin(x)::function,
        22. cos(x)::function,
        23. tan(x)::function,
        24. acos(x)::function,
        25. asin(x)::function,
        26. atan(x)::function,
        27. atan2(x,y)::function,

        . . . . . . . . . ( end of section Math) <<Contents | End>>



        Conversion: toString(radix).


        Arrays are one-dimensional, associative, sparse, heterogeneous, and dynamic. The first index value is always zero. If index i has an item then so do all items with indexes 0 thru to i inclusive -- tho some of these may be empty. A new item with a non-integer index is added after the last defined item -- and so, in effect, has two indexes: a number and its given index.
        1. length::property=range of indexes with items.

          JavaScript 1.1 Arrays:

          1. join()::method=returns a string containing all elements concatenated together.
          2. reverse()::method=takes items and puts them into the opposite order.
          3. sort(c)::method=in place reordering so that for all adjacent items a,b c(a,b)<=0.

            JavaScript 1.2 adds: slice, splice, push, pop, unshift, shift, ... but some of these are not implemented in JScript1.2

        Features in a Browser

          First the current document is available as a property of the global object document. Each part is a property of this object and is even accessible by name. The name comes from the NAME attribute given in the HTML page. There are many other attributes as well. As a quick example suppose we have a FORM with NAME=myform which contains an INPUT with NAME=myinput then we will have these objects available to us in JavaScript:
          To document the property of being named in HTML I use the symbol named:
        1. named::= Net{ name:string, taken from the HTML paged }.

          In a browser the global object is the current window. It may contain other rectangular sub areas that are also treated as windows by JavaScript.

        2. window::=named with following, The elements in a form are an array of many different types of element:
        3. form::= named with{ elements:#input, ...},
        4. input::=named with following
            See Input above.
          1. form:form,
          2. type:input_type, in Navigator 3
          3. input_type::="button" | "checkbox" | "hidden" | "password" | "radio" | "reset" | "select" | "submit"| "text" | "textarea".

          4. if input_type <> "select" then value:string.

          5. if input_type = "select" then options:#option, an array of options,

          6. ...

          (End of Net)

        . . . . . . . . . ( end of section Features in a Browser) <<Contents | End>>

      . . . . . . . . . ( end of section Essential Predefined Features) <<Contents | End>>

      Hints and Tricks

        Declare Variables Early

        A variable is local if there is a declaration anywhere in its function. This is confusing if the variable is used before it is declared. This usage looks like a global variable but is actually local.

        Don't use with

        The symbol "with" is supposed to be like "with" in Pascal -- an abbreviation. However it has some unexpected effects.

        Hiding JavaScript from non-JavaScript Browsers

        Place the script and its <script> and </script> tags, inside an SGML comment... with the last tag made to look like a JavaScript comment:
            // --->

        Doing something for Non-scripting Browsers

        Use the "<NOSCRIPT>" tag:
                 <NOSCRIPT> any_HTML_text </NOSCRIPT>
        The HTML is only displayed if the browser can't handle scripts.

        Distinguishing Undefined from Null

        Use the typeof operator:
                 typeof null         "object"
                 typeof v       "undefined"

        Finding the "Class" of an expression

        First use the typeof operator to sure that the expression returns an object and then use the constructor property to find the name of the function that constructed the object.

        Embedding an HTML SCRIPT inside JavaScript

        If you need to have the string "</SCRIPT>" in a JavaScript statement in a HTML script.... then write it like this: "<\/SCRIPT>".

        Avoid Coercing Arrays to Boolean

        If a is an array then in conditions like
        different versions of JavaScript do different things.

        Null and NaN are False

        When a number is converted to boolean value (in an if(...) for example) the result is false for zero and true for any non-zero except the "Not a Number" (NaN) value and the "Undefined" value. Undefined and NaN are both false.

        Determining the Version in a Browser

        You can have a series of SCRIPT tags at the start of a page that have different language attributes and set a global property indicating the version.

        Testing for the Existence of a Function

        A function f of an object x is invoked by x.f(...) but is stored as property x.f -- no brackets. So to find out if a function exists in use
                 if ( x.f ) // use x.f()
                 else //avoid using x.f()
        This can be used to work around platform and version incompatibilities.

      . . . . . . . . . ( end of section Hints and Tricks) <<Contents | End>>

      Symbols Used

    7. MS::Languages->Languages=`a function that distorts the syntax and semantics of languages`.
    8. TBA::="To Be Announced".
    9. For all X, O(X)::= empty|X, -- optional X.
    10. For all X, List(X)::= X #("," X), -- an X or an X,X or X,X,X or ... .
    11. double_quote::="\"".
    12. empty::=. -- string with nothing in it.
    13. awk::=`a language created by Aho, Weinberg, and Kernighan to help programmers to solve simple data processing problems quickly and easily`.

    14. Net::=A set of interrelated attributes and constraints, defines the mathematical equivalent of a class in C++ [ maths.syntax.html ]

    15. with::=indicates the extension of a logical system by adding a set of terms and constraints to those already existing. [ maths.syntax.html ]

      See Also

    16. C::= See http://www.csci.csusb.edu/dick/samples/c.syntax.html.
    17. CPP::= See http://www.csci.csusb.edu/dick/samples/c++.syntax.html.

    18. HTML::= See http://www.csci.csusb.edu/dick/samples/comp.html.syntax.html.
    19. Java_keywords::= See http://www.csci.csusb.edu/dick/samples/java.html.

    20. Java::= See http://www.csci.csusb.edu/dick/samples/java.html.

    21. JavaScript_introduction::= See http://www.accredited-online-college-degrees.com/javascript.html.

    22. RE::= See http://www.csci.csusb.edu/dick/samples/regular_expressions.html.

    23. SGML::= See http://www.csci.csusb.edu/dick/samples/comp.text.sgml.html.
    24. URL::= See http://www.csci.csusb.edu/dick/samples/com.html.syntax.html#Universal Resource Locators


      (Flanagan98): David Flanagan, JavaScript: The Definitive Guide, O'Reilly 1998.

      Here [ 240148421?cid=DDJ_nl_upd_2013-02-12_h&elq=5415a33d4b5d40b6a2f2bb89ff7e3aa5 ] is a slide show that describes some books to help you learn JavaScript...

    . . . . . . . . . ( end of section JavaScript) <<Contents | End>>

( End of document ) <<Contents | Top