Custom namespaces and WinJS.Namespace

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

The WinJS.Namespace.define function allows you to create your own namespace as a way of organizing your code.

When you create a type or other element in a namespace, you reference it from outside the namespace by using its qualified name: Namespace.Type.

You should define your elements before you define the namespace, and simply add references to these elements in the namespace definition. If you define your elements inside the namespace definition, you may try to use the this keyword to refer to other members of the namespace when this refers to something else.

In general, the best way to define namespace members is to do so inside a module closure, defining the namespace elements first and then adding them to the namespace definition. The members must be defined before they are added to the namespace definition.

(function () {
     var Robot = WinJS.Class.define(function (name) {
            this.name = name;
        },
        { modelName: "" },
        { harmsHumans: false, obeysOrders: true }
    );

    WinJS.Namespace.define("Robotics", {
        Robot: Robot
    });
})();

In other code, you can call these members as follows:

var myRobot = new Robotics.Robot("Sam");
var harm = Robotics.Robot.harmsHumans;

You should not to refer to the namespace before it is defined. If you do so, as in the code below, you get the error "namespace name is undefined."


var Robot = WinJS.Class.define(function (name) {
         this.name = name;
    },
    { modelName: "" },
    { harmsHumans: false, obeysOrders: true }
 );

// Don't do this.
var myRobot = new Robotics.Robot("mike");

WinJS.Namespace.define("Robotics", {
    Robot: Robot 
});

You can add properties to a namespace multiple times if you need to. You might want to define a function in a different file from the one in which the rest of the namespace elements are defined. Or you might want to reuse a function in several namespaces. In the following code, WinJS.Namespace.define is called twice to add the getAllRobots function and the findRobot function to the Robotics namespace.

var Robot =  WinJS.Class.define( function(name) {
        this.name = name;
});
        
function getAllRobots() {
    return allRobots;
}

var allRobots = [
    new Robot("mike"),
    new Robot("ellen")
];

WinJS.Namespace.define("Robotics", {
    Robot: Robot,
    getAllRobots: getAllRobots
});

function findRobot(robotName) {
    for (var i in allRobots) {
        if (allRobots[i].name == robotName) {
            return llRobots[i];
        }
    }
}

WinJS.Namespace.define("Robotics", {
    findRobot: findRobot
});

Nesting namespaces

You can create nested namespaces by defining individual namespaces with dot notation, for example "Robotics.Search". It's not a good idea to use a lot of nesting in your code, because nesting can make the code very complex. Here's an example of a nested namespace:

var Robot =  WinJS.Class.define( function(name) {
        this.name = name;
});

function findRobot(robotName) {
    for (var i in allRobots) {
        if (allRobots[i].name == robotName) {
            return allRobots[i];
        }
    }
}

var allRobots = [
    new Robot("mike"),
    new Robot("ellen")
];

function getAllRobots() {
    return allRobots;
}

WinJS.Namespace.define("Robotics", {
    Robot: Robot
});
    
WinJS.Namespace.define("Robotics.Search", {
    findRobot: findRobot
});

var robot = Robotics.Search.findRobot("mike");