April 2002 Draft
JavaScript 2.0
Libraries
Types
previousupnext

Wednesday, December 5, 2001

Predefined Types

The following types are predefined in JavaScript 2.0:

Type Set of Values Implicit Coercions
Never No values None
Void undefined Any value undefined
Null null undefined null
Boolean   true and false undefined false
Integer Double-precision IEEE floating-point numbers that are mathematical integers, including positive and negative zeroes, infinities, and NaN undefined NaN
Number Double-precision IEEE floating-point numbers, including positive and negative zeroes, infinities, and NaN undefined NaN
char  Single 16-bit unicode characters undefined char("\0")
String Immutable strings of unicode characters, including null undefined null
Function All functions, including null undefined null
Array Same as Array[Object] undefined null
Array[t] null as well as all arrays capable of holding elements of type t undefined null
StaticArray[t] null as well as all writable arrays capable of holding elements of type t undefined null
DynamicArray[t] null as well as all writable, resizable arrays capable of holding elements of type t undefined null
ConstArray Same as ConstArray[Object] undefined null; an Array is copied to make a ConstArray
ConstArray[t] null as well as all constant arrays capable of holding elements of type t undefined null; an Array[t] is copied to make a ConstArray[t]
Type All types, including null undefined null
Prototype All prototype-based objects, including null None
Object All values, including null and undefined None
- t Any value belonging to type t except null
~ t undefined or any value belonging to type t undefined undefined; any other implicit coercions already defined for t

Unlike in JavaScript 1.5, there is no distinction between objects and primitive values. All values can have methods. Values of some classes are sealed, which disallows addition of dynamic properties. User-defined classes can be made to behave like primitives by using the class modifier final (and primitive, once it is implemented).

The above type names are not reserved words. They can be used as names of local variables or class members. However, they are defined as constants in the global scope, so a package cannot use them to name global variables.

Object is the supertype of all types. Never is the subtype of all types. Never is useful to describe the return type of a function that cannot return normally because it either falls into an infinite loop or always throws an exception. Never cannot be used as the type of a variable or parameter. Void is useful to describe the return type of a function that can return but that does not produce a useful value. See rationale.

A literal number is a member of the type Number; if that literal has an integral value, then it is also a member of type Integer. A literal string is a member of the type String. There are no literals of type char; a char value can be constructed by an explicit or implicit conversion.

An object created with the expression new Object or new f where f is a function has the type Prototype. There are no direct instances of type Object. Only objects of type Prototype have a prototype chain.

Array Types

The description of array types is out of date.

The array types have the following subtype relationships:

Array is an abstract class; creating an instance of Array or Array[t] actually creates an instance of DynamicArray[t] but with JavaScript 1.5-compatible semantics for the constructor arguments. The expression new  a(elt1elt2...) where a is StaticArray[t], DynamicArray[t], ConstArray, or ConstArray[t] creates an instance of the corresponding array type with the given elements; this is true even if there is only one element given. The expression a(n) where a is StaticArray[t] or DynamicArray[t] and n is a number creates an array with n elements whose value is the default value of type t. The expression a(b) where a is StaticArray[t], DynamicArray[t], ConstArray, or ConstArray[t] and b is any array with element type t or more specific coerces b into array type a.

An instance of DynamicArray[Object] may have missing elements (holes) and is automatically expanded when an out-of-bounds element is written. None of the other array types allows holes, and they do not automatically expand. An instance of DynamicArray[t] where t is not Object can be resized by explicitly writing its length property.

Instances of non-ConstArray array types are equal only when they are the same object. Instances of ConstArray array types are equal when they have the same contents and the same element type t.

User-Defined Types

Any class defined using the class declaration is also a type that denotes the set of all of its and its descendants’ instances. These include the predefined classes, so Object, Date, etc. are all types. null is an instance of a user-defined class. undefined is never an instance of a user-defined class.

Meaning of Types

Types are generally used to restrict the set of objects that can be held in a variable or passed as a function argument. For example, the declaration

var x:Integer;

restricts the values that can be held in variable x to be integers.

A type declaration does not affect the semantics of reading the variable or accessing one of its properties. Thus, as long as expression new MyType() returns a value of type MyType, the following two code snippets are equivalent:

var x:MyType = new MyType();
x.foo();
var x = new MyType();
x.foo();

This equivalence always holds, even if these snippets are inside the declaration of class MyType and foo is a private field of that class. As a corollary, adding true type annotations does not change the meaning of a program.

Type Expressions

The language cannot syntactically distinguish type expressions from value expressions, so a type expression can be any compile-time constant expression that evaluates to a type. See also the other possible type constructors.

A type is also a value (whose type is Type) and can be used in expressions, assigned to variables, passed to functions, etc. For example, the code

const R:Type = Number;
function abs_val(x:R):R {
  return x<0 ? -x : x;
}

is equivalent to:

function abs_val(x:Number):Number {
  return x<0 ? -x : x;
}

Implicit Coercions

Implicit coercions can take place in the following situations:

In any of these cases, if v t, then v is passed unchanged. If v t, then if t defines an implicit mapping for value v then that mapped v is used; otherwise an error occurs.

undefined can be implicitly coerced to any type except Never.

Explicit Coercions

An explicit coercion performs more aggressive transformations than an implicit coercion. To invoke an eplicit coercion, use the type as a function, passing it the value as an argument:

type(value)

For example, Integer(258.1) returns the integer 258, and String(2+2==4) returns the string "true".

If value is already a member of type, the explicit coercion returns value unchanged. If value can be implicitly coerced to type, the explicit coercion returns the result of the implicit coercion. Otherwise, the explicit coercion uses type’s explicit mapping.


Waldemar Horwat
Last modified Wednesday, December 5, 2001
previousupnext