July 2000 Draft
JavaScript 2.0
Core Language
Concepts
|
Friday, April 28, 2000
A value is an entity that can be stored in a variable, passed to a function, or returned from a function. Sample values include:
undefined
null
5
(a number)true
(a boolean)"Kilopi"
(a string)[1, 5, false]
(a three-element array){a:3, b:7}
(an object with two properties)function (x) {return x*x}
(a function)String
(a class, a function, and a type)A type t represents two things:
The set S indicates which values are considered to be members of type t. We write v t to indicate that value v is a member of type t. The mapping M indicates how values may be coerced to type t. For each value v already in S, the mapping M must map v to itself.
A value can be a member of multiple sets, and, in general, a value belongs to more than one type. Thus, it is generally not useful to ask about the type of a value; one may ask instead whether a value belongs to some given type. There can also exist two different types with the same set of values but different coercion mappings.
On the other hand, a variable does have a particular type. If we declare a variable x of type t, then whatever value is held in x is guaranteed to have type t, and we can assign any value of type t to x. We may also be able to assign a value v t to x if type t's mapping specifies a coercion for value v; in this case the coerced value is stored in x.
Every type represents some set of values but not every set of values is represented by some type (this is required for logical consistency -- there are uncountably infinitely many sets of values but only countably infinitely many types).
Every type is also itself a value -- we can store a type in a variable, pass it to a function, or return it from a function.
If type a's set of values is a subset of type b's set of values, then we say that that type a is a subtype of type b. We denote this as a b.
Subtyping is transitive, so if a b and b c, then a c. Subtyping is also reflexive: a a. Also, if v t and t s, then v s.
The set of all values is represented by the type any
, which is the supertype of all types. A variable with
type any
can hold any value. The set of no values is represented by the type none
, which is the
subtype of all types. A function with the return type none
cannot return.
A class is a template for creating similar values, often called objects or instances. These instances generally share characteristics such as common methods and properties.
Every class is also a type and a value. When used as a type, a class represents the set of all possible instances of that class.
A class C can be derived from a superclass S. Class C can then inherit characteristics of class S. Every instance of C is also an instance of S, but not vice versa, which, by the definition of subtyping above, implies that C S when we consider C and S as types.
The subclass relation imposes a hierarchy relation on the set of all classes. JavaScript 2.0 currently does not support multiple inheritance, although this is a possible future direction. If multiple inheritance were allowed, the subclass relation would impose a partial order on the set of all classes.
An interface is also a template for creating similar values, often called objects or instances. These instances generally share characteristics such as common methods and properties. An interface's methods may (but don't have to) be abstract.
Every interface is also a type and a value. When used as a type, an interface represents the set of all possible instances of that interface.
Classes and intefaces differ when it comes to inheritance. A class (or interface) C may inherit from an interface I. In this case, however, C is not a subtype of I. On the other hand, an instance c of C may be coerced to type I, which creates an instance i of I. Coercing i to type C yields the original instance c. A class or interface may inherit from multiple interfaces.
A scope represents a region of JavaScript source code. The JavaScript statements or expressions package
,
class
, function
, and scope{ }
define scopes in the source code. The top level
of a JavaScript program is also a scope, called the global scope. A scope is a static entity that does not change while a
JavaScript program is running (except that if the program calls eval
then new JavaScript source code will be
created which may share existing scopes or create its own scopes).
A scope may be contained inside another scope. If two scopes overlap, one must be contained entirely within the other, so scopes form a hierarchy. The global scope contains all other scopes.
Scope information is used at run time to help with variable and property lookups and visibility checks.
A scope should not be confused with an activation frame, which is a runtime binding of local variable names to values. A scope should also not be confused with a namespace.
A namespace parametrizes the mapping of names to values. A namespace attribute N may be attached to the
declaration of any name or property p. That namespace then acts like a lock on accesses to p: another
piece of code may access p only by qualifying it with that namespace (N::
p)
or by executing a use
namespace
N statement in a scope surrounding the access of p.
A namespace is a value that can be passed as the first operand of the ::
operator.
A namespace N may inherit from another namespace M, in which case N grants access to every property that M grants access to. Unlike in C++, a namespace is not a scope and does not contain any names or properties itself; a namespace only modifies the accessibility and visibility of names or properties attached to activation frames, classes, interfaces, or objects.
public
is the default namespace for declarations; a use
namespace
public
statement is implicit around the global scope. Each package has a predefined, anonymous package
namespace and
each class and interface has a predefined, anonymous private
namespace; these provide member access control.
User-defined namespaces may also be used for more flexible member access control.
Waldemar Horwat Last modified Friday, April 28, 2000 |