April 2002 Draft
JavaScript 2.0
Core Language
Concepts
previousupnext

Friday, April 12, 2002

Values

A value is an entity that can be stored in a variable, passed to a function, or returned from a function. Sample values include:

Types

A type t represents three 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 I indicates how values may be implicitly coerced to type t. For each value v already in S, the mapping I must map v to itself. The mapping E indicates how values may be explicitly coerced to type t. For each value v in the domain of I, E must map v to the same value as I maps v. In other words, any implicit coercion is also an explicit coercion but not vice versa.

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 be a member of 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 an implicit 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 and can be stored in a variable, passed to a function, or returned from a function.

Type Hierarchy

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 Object, which is the supertype of all types. A variable with type Object can hold any value.

The set of no values is represented by the type Never, which is the subtype of all types. A function with the return type Never cannot return.

Classes

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.

Interfaces

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 implicitly coerced to type I, which creates an instance i of I. Implicitly coercing i to type C yields the original instance c. A class or interface may inherit from multiple interfaces.

Members

A class or interface typically contains a set of members, which can be variables, functions, etc. Members are classified as either instance or global members. Instance members become properties of instances of the class. Global members become properties (sometimes called class properties) of the class object itself; a class has only one global member with a given name.

Members can have attributes which modify their behavior.

Instances

An instance (sometimes called an object) contains a set of properties. An instance belongs to a particular class and must have properties for the instance members defined in that class and its ancestors; these bindings are made when the instance is created. An instance may also have additional dynamic properties, which can be added and deleted any time after the instance has been created.

Unless specified otherwise, each separately created instance has a distinct identity. The default === operator returns false when applied to two different instances or true when applied to the same instance (with the exception of NaN, which always compares unequal to itself).

Instances provide the appearance of lasting forever, although an implementation is expected to garbage-collect them when they are no longer reachable.

Properties

A property is a runtime binding of a property name to a value. The values of some properties can change. Properties can be fixed or dynamic. Fixed properties are declared as members of a class definition and are created at the time the object is constructed. Dynamic properties can be added to an object at any time after the object was created. All JavaScript 1.5 properties are dynamic.

Properties can have attributes. Fixed properties inherit their attributes from the corresponding members.

Property Names

A property name identifies a property of an instance and consists of a namespace N, an identifier id, and a class C. There is no language syntax for fully specifying a property name; in this specification property names are denoted using the notation N::idC. If the property is fixed, then C is the class in which the corresponding member is defined. If the property is dynamic, then C is the instance’s most derived class. If the member is defined in an interface, then C is a class that implements that interface.

An instance can contain at most one property for each property name. An instance can contain multiple properties with the same namespace N and name id but different classes C; in this case the property with the most derived class C is said to override the others. The overridden properties are still present in the instance and can be accessed using the super operator.

Scopes

A scope represents one of the following delimited portions of JavaScript source code. Some scopes are further distinguished as being regional scopes, as indicated in the table below.

Nonterminal  Regional Description
Program yes The top level of a program
PackageDefinition yes A package definition
ClassDefinition yes A class definition
InterfaceDefinition yes An interface definition
FunctionDefinition yes A function definition
FunctionExpression   yes A function expression
Block no* A block (but not a group of directives prefixed with attributes)
ForStatement no* A for statement
CatchClause no* A catch clause of a try statement

*These three scopes become regional scopes if the next outer scope is a class 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 other than the top level of a program (the global scope) is always contained inside another scope. If two scopes overlap, one must be contained entirely within the other, so scopes form a hierarchy.

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. A scope should also not be confused with a namespace.

Activation Frames

An activation frame contains a set of runtime bindings of all qualified names defined in a scope to values. A new activation frame comes into existence each time the scope is entered. A function closure captures a reference to the activation frame in which it was created. Activation frames provide the appearance of lasting forever, although an implementation is expected to discard them after the scope is exited and any closures that captured the activation frame have been garbage-collected.

The values of some bindings in an activation frame can change. The bindings’ values begin in an uninitialized state. It is an error to read a binding in an uninitialized state.

Activation frame bindings can have attributes which modify their behavior.

Qualified Names

A qualified name consists of a namespace N and an identifier id. In this specification qualified names are denoted using the notation N::id. An activation frame can contain at most one binding for each qualified name.

Namespaces

A namespace parametrizes names. 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 using N::p or by executing a use namespace(N) directive in a scope surrounding the access of p. 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.

A namespace is a value that can be passed as the first operand of the :: operator.

public is the default namespace for declarations; a use namespace(public) directive is implicit around the global scope. Each package has a predefined, anonymous internal namespace and each class and interface has a predefined, anonymous private namespace; these provide access control. User-defined namespaces may also be used for more flexible access control.


Waldemar Horwat
Last modified Friday, April 12, 2002
previousupnext