ECMAScript 4 Netscape Proposal
Libraries
Types
|
Wednesday, June 4, 2003
The following types are predefined in ECMAScript 4:
Unlike in ECMAScript 3, 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
.
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
f where f is a function has the type
Object
.
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.
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.
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.
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 can take place in the following situations:
undefined
is implicitly coerced
to type tIn 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.
An explicit coercion performs more aggressive transformations than an implicit coercion. To invoke an explicit 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, June 4, 2003 |