|
|
The empty statement does nothing. Its primary use is to separate
statements. (See automatic semicolon
insertion.)
a = 3; a++; var b = 3; if (a) b = 9;
|
{
statement_1
...
statement_n
}
|
The block statement sequentially executes statement_1 through
statement_n.
The expression statement executes any expression expr.
var id_1 [= expr_1], ..., id_n [= expr_n]
|
The var statement declares and initializes variables
id_1 through id_n. If expr_i exists, id_i
gets its value, otherwise id_i gets undefined .
The var statement is most important in declaring
local variables in a function. Although variables can be used without the
var statement, undeclared variables are necessarily global.
Local variable declaration
var b = "global";
var a = "initial";
function foo()
{
var b = "local";
a = "global";
}
foo();
a + ' ' + b
|
global global
|
Unlike Java and C, the scope of the declared variable is the
entire function, not the enclosing block. So in the following
example, the second declaration of a is equivalent to a simple
assignment.
Local scope is entire function
function foo()
{
var a = "initial";
{
var a = "inner";
}
return a;
}
foo();
|
inner
|
if (cond)
statement
[else
else-statement]
|
The if statement conditionally executes code. If cond
is true, it executes statement. Otherwise
it executes else-statement if the else statement exists.
cond may be any expression, except that assignments must be
enclosed in parentheses to ensure assignment is not confused with
equality.
Illegal
if (a = 3)
writeln("bad bad bad");
|
Okay
if ((a = 3))
writeln("discouraged, but okay");
|
Here are some simple examples of the if statement.
Taken Branch
a = 13
if (a < 20)
writeln("small");
|
small
|
Not Taken Branch
a = 30
if (a < 20)
writeln("small");
|
|
Else Statement
a = 30
if (a < 20)
writeln("small");
else
writeln("large");
|
large
|
switch (expr) {
case literal_1:
statement_list_1
...
case literal_n:
statement_list_n
[default:
default_statement_list]
}
|
The switch statement executes one of a number of branches. It
evaluates expr and selects the matching literal_i. If
none of the literals match, it selects default . It then
executes statement_list_i and any following statements in the
switch . A branch in a statement_list_i breaks
out of the switch statement.
switch fall-through
switch (1) {
case 0: writeln(0);
case 1: writeln(1);
writeln(2);
case 3: writeln(3);
break;
case 4: writeln(4);
}
|
1
2
3
|
switch default
switch ("c") {
case "a":
writeln(0);
break;
case "b":
writeln(1);
break;
default:
writeln("default");
break;
}
|
default
|
The while statement repeatedly executes code. While cond
is true, it executes statement.
Like if, cond may be any expression,
except that assignments must be enclosed in parentheses to ensure
assignment is not confused with equality.
i = 4
while (i--)
writeln("Hello, world")
|
Hello, world
Hello, world
Hello, world
Hello, world
|
for ([init]; [cond]; [incr])
statement
|
The for statement repeatedly executes code. While cond
is true, it executes statement. After executing
statement, it executes incr.
The for statement is equivalent to:
init;
while (cont) {
statement;
incr;
}
|
except it executes incr after a continue .
for (var i = 0; i < 4; i++)
writeln("Hello, world")
|
Hello, world
Hello, world
Hello, world
Hello, world
|
for ([var] i in expr])
statement
|
The for ... in statement iterates over property names of
an object. It does not guarantee any order.
o = {a:1, b:2, c:3}
for (var i in o)
writeln(i);
|
c
a
b
|
o = [3, 2, 1]
for (var i in o)
writeln(i);
|
2
0
1
|
do ... while
| JavaScript 1.2 |
do
statement
while (expr)
|
do executes statement as long as expr is true.
statement is guaranteed to be executed at least once.
i = 7
do
writeln(i);
while (i < 3);
|
7
|
break immediately terminates an enclosing loop or jumps to the
end of a labelled block.
continue jumps to the end of a loop, allowing it to execute
again.
labeled statements
| JavaScript 1.2 |
A labeled statement executes as any other statement, except that a
break executed in the statement will terminate the statement.
If statement is a loop, a continue within the
statement will continue the loop.
foo:
{
a = 13;
break foo;
a = 19;
}
writeln(a);
|
13
|
loop:
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 10; j++) {
if (j == 3)
break loop;
}
}
writeln(i);
|
0
|
The return statement immediately terminates the enclosing
function and returns the value of expr as the function's
value. If expr is missing, the function returns undefined .
Returning a value
a = 12
function foo() {
return 1 + 3;
a = 19; // never executed
}
foo() + ' ' + a
|
4 12
|
Returning without a value
a = 12
function foo() {
return
1 + 3 // treated as following statement, so never executed.
}
foo() + ' ' + a
|
4 12
|
The with extends the variable scope by looking up variables in
expr before using local or global variables.
Simple use of with
o = { a : 13 }
a = 1
with (o) {
writeln(a);
a = 7
}
writeln(a + ' ' + o.a)
|
13
1 7
|
Resin provides some syntactic sugar to JavaScript's prototype-based
object inheritance to simplify objects creation.
class object-name [extends parent-object] {
function member0(...) { ... }
...
function membern(...) { ... }
}
|
The class statement simplifies JavaScript objects without
adding any new semantic power to the language.
Only functions are currently allowed as members in the class.
The following are (almost) equivalent. The first using Resin's
class extension, and the second following JavaScript's definitions.
The only difference between the two is that the JavaScript version
unavoidably binds the functions to the global object.
Sample class definition
class Car {
function getColor() { return this.color; }
function setColor(color) { this.color = color; }
function start() { this.started = true; }
function Car()
{
this.color = "red";
this.started = false;
}
}
|
The Car class using strict EcmaScript
function Car()
{
this.color = "red";
this.started = false;
}
function getColor() { return this.color; }
Car.prototype.getColor = getColor;
function setColor(color) { this.color = color; }
Car.prototype.setColor = setColor;
function start() { this.started = true; }
Car.prototype.start = start;
|
extends
The optional extends part of the class eases inheritance.
Again, this adds nothing to the semantic power of the language but
makes the code far more readable.
The following are equivalent
Using extends in Resin
class Car {
}
class Honda extends Car {
}
|
The equivalent of extends in strict EcmaScript
function Car() {}
function Honda() {}
Honda.prototype.prototype = Car.prototype;
|
Resin extends JavaScript to support Java exceptions. By supporting
Java exceptions, Resin allows a tighter binding to Java components.
If a server-side bean throws an exception, a Resin script can catch it
and gracefully handle the error.
Since the JavaScript programs are compiled into Java bytecodes, the
exception handling mechanism is essentially the same as for Java. The
only real difference is the pattern matching for selecting a catch
block.
try
protected statement
catch (exception_1 [var_1])
handler_statement_1
...
catch ([exception_n [var_n]])
handler_statement_n
|
This syntax is essentially the same as Java's exception handling.
For clarity, repeating catch blocks and the optional finally block
have been omitted.
protected statement list
catch ([exception [var]])
handler statement
|
The second form of the catch block protects all statements in the
enclosing block up to the catch statement. Scripts can use this to
establish error handlers at the end of the script without having to
wrap the bulk of the script in a try block.
for (var i = 0; i < 10; i++) {
addBook(authors[i], titles[i], prices[i]);
catch (SQLException e) {
writeln("Failed database insertion: " + e);
}
}
|
Matching Exceptions
Resin exception matching uses a string suffix match instead of the
Java type match. Resin compares the catch
statement name to the thrown exception's class name. If the class
name ends in the catch statement name, the exception is considered to
match.
Like Java's exceptions, if the exception class does not match,
Resin will try the parent for a match. However, Resin will only catch
descendants of Exception . It will not catch
Throwable nor will it catch Error or its
descendants.
If the catch expression is empty, it will match all exceptions.
try {
foo();
} catch (IOException) {
}
|
java.io.Exception caught
java.io.FileNotFoundException caught
java.lang.Exception ignored
com.foobar.IOException caught
|
try
protected statement
finally
handler statement
|
protected statement list
finally
handler statement
|
The finally statement guarantees the protected statement will be executed.
The handler statement will execute for normal execution,
for exceptions, and when break and return
statements leave the protected statement.
The throw statement throws an exception. The Java VM
unwinds the executation stack until it finds the nearest matching
catch handler. All finally blocks are executed and
synchronization locks are released.
synchronize (object)
statement
|
- Convert the JavaScript object to its Java
equivalent. For Java wrapped objects, this
just involves unwrapping the object. Pure JavaScript objects are
unconverted.
- Acquire Java object monitor using the JVM monitorenter.
- Evaluate statement
- Release the monitor on any exit: normal,
break , return , or exception.
The following example synchronizes the underlying Java
HashMap, not the JavaScript wrapper.
map = new java.util.HashMap();
synchronize (map) {
map.put("foo", map.get("foo") + 1);
}
|
The following example synchronizes the Number Object, not the
JavaScript primitive number.
number = new Number(1);
number.a = 1
synchronize (number) {
number.a += 3;
}
|
Imports functions from another file, allowing scripts to
share common functions and allowing developers to break their code
into manageable chunks.
The imported file is treated as its own JavaScript file with its
own global object. Its global statements execute before the global
code of the importing file.
The import statement only imports the functions from the imported
file. Global variables are not imported. The imported functions use
the global object of the imported file, not the global object their
imported into.
Imported scripts are looked up along a SCRIPTPATH. The initial
value of SCRIPTPATH is:
.:$RESIN_HOME/scripts
Where $RESIN_HOME/lib/resin.jar is the resin.jar file.
com/caucho/test.js
var a = 10;
writeln("Import Execution");
function getA() { return a; }
|
import com.caucho.test;
writeln("Hello, world");
|
Import Execution
Hello, world
|
Import functions but not variables
var a
import com.caucho.test;
writeln(getA() + ' ' + a);
|
Import Execution
10 undefined
|
Copyright © 1998-2000 Caucho Technology. All rights reserved.
Last modified: Thu, 16 Sep 1999 14:56:48 -0700 (PDT)
|