July 2000 Draft
JavaScript 2.0
Core Language
Packages
|
Friday, May 26, 2000
Packages are an abstraction mechanism for grouping and distributing related code. Packages are designed to be linked at run time to allow a program to take advantage of packages written elsewhere or provided by the embedding environment. JavaScript 2.0 offers a number of facilities to make packages robust for dynamic linking:
A package is defined using the following syntax:
A PackageName is either a literal string or a series of dot-separated
identifiers (a CompoundPackageName). A CompoundPackageName
is converted to a string by concatinating the names of the identifiers, separated by period (.
) characters.
An earlier version of this proposal used URIs as package names, which simplified the process of finding packages and avoiding package name clashes.
The Block contains the body of a package P.
The Block is evaluated at the time package P
is loaded. Any public
top-level properties are available to other packages that import package P.
Any public
class and interface properties are available to all other packages, regardless of whether they import
package P. Top-level, class, and interface properties defined by P in another namespace N
are available to other packages only if they use
namespace
N or qualify the access with
namespace N.
A package is loaded (its body is evaluated) when the package is first imported or invoked directly (if, for example, the
package is on an HTML web page). Some standard packages are loaded when the JavaScript engine first starts up. When a package
is loaded, its statements are evaluated in order, which may cause other packages to be loaded along the way when import
statements are encountered. Circularities are not allowed in the graph of package imports.
Two attempts to load the same package in the same environment result in sharing of that package. What constitutes an environment is necessarily application-dependent. However, if package P1 loads packages P2 and P3, both of which load package P4, then P4 is loaded only once and thereafter its code and data is shared by P2 and P3.
To create packages A and B that access each others' symbols, define instead a hidden package C that consists of all of the code that would have gone into A and B. Package A would then import C and reexport the symbols that should be visible in A. Similarly, package B would import C and reexport the symbols that should be visible in B.
A package P can reference another package Q via an import
statement:
An import
statement does the following for each ImportBinding:
scope const
-bind
it to P.public
top-level entity n in P, bind an alias P::
n
(n in namespace P) to P's n in the current scope.public
top-level entity N::
n (n in namespace
N) in P, bind an alias N::
n to P's N::
n
in the current scope.use
prefix was specified, evaluate use
namespace
P.All definitions can be imported except for attribute definitions.
If package P defines a public
top-level entity n and package Q imports P
using import PkgP = P
, then package Q can refer to n as either PkgP.
n
or PkgP::
n. If package Q imports P using use import PkgP = P
,
then package Q can also refer to n as plain n as long as it does not conflict with any n
defined in Q or some other package imported by Q.
If package P defines a top-level entity n in namespace N and package Q imports
P using either import PkgP = P
or use import PkgP = P
,
then package Q can refer to n as either PkgP.
N::
n or
N::
n. Package Q can execute use
namespace
N
to be able to refer to n as plain n (barring name collisions).
Waldemar Horwat Last modified Friday, May 26, 2000 |