Chapter 2 The DynaScript Language


Objects

DynaScript is object-oriented, which means it supports objects and the fundamental object-oriented concepts of:

You can define your own custom object types (also called classes). You can then create as many instances of each class as you require.

Predefined objects

DynaScript also includes a number of predefined objects that simplify the task of developing database-driven content. For more information, see "DynaScript Predefined Objects".

Properties and methods

An object is a convenient way to collect a set of related information (properties) into one place, together with the actions (methods) that manipulate that information.

Note  

Case-sensitive names
The names of object properties and methods are case-sensitive.

Properties

A property is a variable in an object that describes some part or attribute of the object.

A property can be any datatype. Objects can contain other objects as properties.

Property names must be unique within the scope of the class and its ancestor classes (if any).

You can access an object property using standard dot notation:

objectName.propertyName

For example, for an object called sampleEmployee , you could assign "Homer" as the value of its name property:

sampleEmployee.name = "Homer";

Methods

A method is a function in an object that acts on one or more properties of the object.

Name scoping depends on how the method was defined:

You can call an object method using standard dot notation:

objectName.MethodName()

Note  

Parentheses must be used
You must use parentheses when calling a method, even if it takes no arguments.

You can define objects as conventional arrays that use integer indexes. For example:

price[0] = 19.95
price[1] = 42.99

You can also use text literals as indexes. In this case, the array notation simply becomes an alternative to the dot notation for object properties. For example:

sampleEmployee.name

can also be referenced as

sampleEmployee["name"]

Note  

Restrictions on integer indexes
Note that, for integer indexes, you cannot use the dot notation interchangeably with the array notation because of property-naming rules. For example, you cannot reference price[2] as price.2 , because 2 is not a valid identifier name (it does not start with a letter). Also, you cannot reference it as price["2"] . You must use the conventional array notation of price[2] .

Object-oriented concepts

Encapsulation

By using an object container to associate properties with the methods that affect them, you can encapsulate the behavior of a conceptual object in one place. This can make testing, maintenance, and subsequent enhancements much easier.

You also avoid having name conflicts for your properties and methods, since instead of being declared globally (where each name must be unique), they are declared as part of an object (where they need be unique only within the scope of the object itself).

Polymorphism

Polymorphism is the ability of different classes of objects to respond to a particular method call in their own ways.

For example, suppose that you define two object classes called salariedEmployee and hourlyEmployee . Each type has its own PrintAllInfo method that prints employee information a certain way.

To print information for an employee, you simply call the PrintAllInfo method for the object. Depending on whether the employee is salaried or hourly, the corresponding PrintAllInfo method will be called automatically. If you add more classes of employees, they can redefine their own PrintAllInfo methods. The actual code that calls PrintAllInfo does not need to be changed to accommodate the new object types.

Polymorphism is particularly powerful when used in conjunction with inheritance.

Inheritance

ECMAScript lets you define new classes from scratch, but it does not support inheritance - the ability to create new classes of objects that are extensions of existing classes.

The simplest form of inheritance is single inheritance, in which a new class can inherit properties and methods from a single parent class.

DynaScript adds single inheritance in the form of the class statement. You can derive a new class from an existing class, adding new properties and methods (or overriding existing properties and methods) as you require.

Inheriting objects also means that you can take better advantage of polymorphism, since derived classes can override (redefine) existing methods defined by their parent class, without needing to change other code that calls these methods.

Defining base classes

To define a base class (one that does not inherit anything from existing classes), you can:

The Dynamo class statement is a more flexible construct (since you can also use it for derived classes) but if you require compatibility with standard ECMAScript you may want to use the function-declaration technique instead.

Using the function statement

To define a base class using the standard function-declaration technique, declare a function using the class name and the property names, assign the property values, and define a method that references the function.

You can define methods inline (inside the class definition), or by assigning method names to existing global functions (outside the class definition). Inline method declaration is preferable, however, since it encapsulates the method within the class and allows methods in different classes to have the same name (making polymorphism possible).

The following example defines an employee class, with three properties (name , title , and managerName ) and one method (PrintAllInfo ) defined inline:

function PrintAllInfo() {
document.WriteLn("Name: " + this.name);
document.WriteLn("Title: " + this.title);
document.WriteLn("Reports to: " + this.managerName);
function employee(name, title, managerName) {
this.name = name;
this.title = title;
this.managerName = managerName;

}
this.PrintAllInfo = PrintAllInfo;
}

For more information, see "function statement".

Using the class statement

To define a base object using the class statement, declare the class name and the property names, assign the property values, and define a method that references the function.

As in the function-declaration technique, you can define methods inline or assign method names to existing global functions.

The following example defines the same employee class used in the function-declaration example:

class employee(name, title, managerName) {
this.name = name;
this.title = title;
this.managerName = managerName;
function PrintAllInfo() {
document.WriteLn("Name: " + this.name);
document.WriteLn("Title: " + this.title);
document.WriteLn("Reports to: " +
this.managerName);
}
this.PrintAllInfo = PrintAllInfo;
}

The only difference in the two examples is the class keyword itself. The main reason for using the class statement is for the additional ability to define derived objects.

For more information, see "class statement".

Extending existing classes by inheritance

A derived class (also called a subclass) extends the definition of an existing class. It inherits the properties and methods of the parent class (also called a superclass), and then adds (or redefines) its own additional properties and methods.

To define a derived class, use the class statement as follows:

For more information, see "class statement".

Example

The following example defines an employee class, then derives a salariedEmployee subclass from it:

class employee(name, title, managerName) {
this.name = name;
this.title = title;
this.managerName = managerName;
function PrintNameAndTitle() {
document.WriteLn("Name, title: " + this.name
+ ", " + this.title);
}
this.PrintNameAndTitle = PrintNameAndTitle;
}
class salariedEmployee(name, title, managerName, salary)
extends employee(name, title, managerName) {
this.salary = salary;
function PrintAllInfo() {
document.WriteLn("Name: " + this.name);
document.WriteLn("Title: " + this.title);
document.WriteLn("Reports to: " +
this.managerName);
document.WriteLn("Salary: " + this.salary);
}
this.PrintAllInfo = PrintAllInfo;
}

Creating instances of classes

Once you've defined an object class, you can start creating specific objects (instances) of that class. If, for example, you've defined a salariedEmployee class, you can then start creating records for salaried employees.

To create instances of a class, you assign a variable using the new operator with the name of the class and the property values for this new instance of the class. The usage is the same whether you used the standard function-declaration technique or the Dynamo class statement.

For more information, see "new operator".

Example

The following example creates salaryEmp as a new instance of the salariedEmployee class, and supplies it with appropriate values for the class properties (name , title , managerName , and salary ).

var salaryEmp = new salariedEmployee("Ned Simpson",
"Technical Writer", "Barney Burns", 80000);

Working with named and indexed members

Named and indexed members are separate entities. For example, if X.a=1 and X.b=2, document.writeline X[0] would not equal 1 but would have a value of undefined. The following example further demonstrates this:

<!--SCRIPT
X.a=1;
X[1]=2;
X.b=3;
X[0]=4;
for(i in X) {
document.writeln( X[i] );
}
-->

Would have this output:

1
3
4
2

The for in statement iterates through named members first, then indexed members.

Paths

You can use both relative and absolute paths when working with DynaScript objects. You can also use a tilde(~ ) with an absolute path instead of the Web site name or Personal Web Server mapping for the following:

For example, if the name of the root document in your Web site is Product and your mapping to that Web site is named product_site and you wanted to open the document price.stm, you could use:

site.GetDocument("/Product/price.stm");
site.GetDocument("/product_site/price.stm");

The first example would work only from within Sybase Central while the second example would work only through a Web server. Using the tilde allows this statement in either situation:

site.GetDocument("~/price.stm");

The above-listed methods, tags, and statements also handle ..\ in a directory path, which specifies that the path is relative to the current directory but is back one level. Each occurrence of ..\ in a directory path specifies that the target directory is back another level. If the number of occurrences of ..\ in a directory path causes the directory to go back further than /Site, an error occurs.

Wildcards

There are two wildcard characters that you can use with site.DeleteDocument(docName) and document.GetDirectory([fileMask, sortOrder]) : * and ?.

Use the * wildcard to represent any number of alphanumeric characters. For example, site.DeleteDocument("/Site/a*.stm") deletes all templates starting with the letter a from the root of the Web site.

Use the ? wildcard to represent a single alphanumeric character. For example, site.DeleteDocument("/Site/a?.stm") would delete template files that started with an a and had one more character in the file name such as aa.stm or ab.stm. The previous example would not delete the files acrobat.stm or a.stm.

 


Copyright © 1999 Sybase, Inc. All rights reserved.