This project is read-only.

Working with namespaces

Namespaces are organizational entities. Their goal is to organize interfaces and classes in virtual spaces avoiding naming collisions.

jOOPL implements namespaces, porting major languages like C# and Java capabilities:
  • Create nested namespaces.
  • Create namespace aliases.
  • Referencing namespaces in order to access its members without full namespace paths.

1. Namespace keyword members

  • $namespace.register
    • Description: Creates a new parent or nested namespace.
    • Parameters:
      1. path: An absolute path as string to the new namespace.
  • $namespace.alias
    • Description: Creates an alias of an existing namespace.
    • Parameters:
      1. namespace: The namespace for which an alias must be created. This must be an object path.
      2. alias: A path as string representing the namespace alias.
  • $namespace.using
    • Description: Imports all classes and interfaces of some given namespace to current global scope.

2. Creating namespaces

A namespace is created by giving period-separated identifiers. The first declared one is the top-most, the next is nested into its parent and so on.

Any namespace is created as child of $global object representing the global jOOPL scope.

Declaring namespaces

For example, a "jOOPL" namespace would be created this way:


And later a "Samples" namespace can be nested to "jOOPL" one:


Or both can be declared in a single operation:


Aliases can be created like this sample:

$namespace.alias(jOOPL.Samples, "Samples");

Note first argument is not an string but an object path.

Adding members like classes to a declared namespace

Once a namespace is declared, interfaces and classes can be added to it with an object path like this:

$global.jOOPL.Samples.ClassA = $def(...);

Since 2.1.0 and above versions, $namespace.register supports a new use case on which it can both register and create a namespace scope in a function where the "this" keyword is the whole namespace:

$namespace.register("namespaceA.namespaceB", function() {
       // The "this" keyword will be the "namespaceB" namespace
       this.ClassA = $def(...);

A good practice: always register a namespace

A good practice in jOOPL is registering the namespace required by some JavaScript code wherever it is required, instead of declaring it in a single file.

$namespace.register checks if the namespace has been already declared and if it this is the case, it skips the namespace registration.

3. The $namespace.using method

jOOPL supports the concept of importing some namespace members in order to avoid accessing classes, interfaces and others with the namespace-qualified path (i.e. SomeNamespace.SomeOtherNamespace.SomeClass).

$namespace.using enforces good practices as it does not support importing members to the global scope (i.e. in the $global object), but it allows the creation of scopes with imported members.

First of all, $namespace.using constructor supports these input parameters:

Parameter name Description
namespaces An array of strings where each string is the full path of the namespaces that must be imported, or a single string literal with an existing namespace full path.
scopedFunc (optional) An anonymous function representing the scope to which namespace imports will be attached at

Namespace scope stored in the standard this keyword

If the $namespace.using(...) is called with the namespace path or paths, and a parameterless function, the whole function body will be a new scope where the this** JavaScript keyword will hold an object having the imported namespace classes and other members:

$namespace.register("MyNamespaceA.MyNamespaceB", function () {
    // Define a class in the namespace
    this.ClassA = $def(...);

// Later, in the same file or another one, some code may need to
// use members (like classes) and it imports child "MyNamespaceB" 
// members into the "this" keyword inside the "scope function":
$namespace.using(["MyNamespaceA.MyNamespaceB"], function() {
        // The "this" JavaScript keyword holds the imported members for 
        // the current scope!
        // No need of accessing the class definition using the full namespace 
        // path anymore!!
        var instance = new this.ClassA();
  • Pros
    • No need of creating a variable.
    • A more compact syntax.
  • Cons
    • In some developments, it may create problems as it changes the meaning of the this** keyword.

Namespace scope in a variable

There are two ways of creating a namespace scope in a variable: either in a scoped function or in a local variable.

The scoped function approach is different to storing the scope in the JavaScript this keyword because, in this case, the this keyword will hold the $global object (see keywords for more information about this).

// Define a class in the namespace
$global.MyNamespaceA.MyNamespaceB.ClassA = $def(...);

// The "scope" input parameter in the function will hold the imported members
$namespace.using(["MyNamespaceA.MyNamespaceB"], function(scope) {
        // The "this" JavaScript keyword holds the imported members for 
        // the current scope!
        // No need of accessing the class definition using the full namespace 
        // path anymore!!
        var instance = new scope.ClassA();

// The local variable will hold the imported members!
var scope = $namespace.using(["MyNamespaceA.MyNamespaceB"]);
  • Pros
    • The scoped function with parameter is safer than the parameterless scoped function, because it avoids conflicts with the this keyword.
    • The this keyword is a synonym of $global keyword (see keywords). This is to enforce good practices and do not fill the standard Window object with garbage.
    • In the case of using a local variable instead of a scoped function, it can be cleaner and elegant, as it does not create any naming conflict nor overriddes the this keyword.
  • Cons
    • In the case of the scoped function with scope parameter, it still override the this keyword and, in some cases, if it is not used carefully, it can create unpredictable results.

Last edited Apr 6, 2013 at 2:31 PM by MFidemraizer, version 23


No comments yet.