This post is a detour from a larger MVC on WinJS post, but code organization is an important topic for developers transitioning from C#/XAML and merits a blog post of its own.

First, a shameless self-promotion update – I will be speaking in 3 weeks at the NYC Code Camp on the topic of getting started with WinJS programming. You can find the details of the conference here.

I will also be speaking at the MCT Summit on October 26, delivering a talk on advanced WinJS programming and integrating with the cloud. Details of this conference can be found here.
Now we can get to the meat of the matter. WinJS introduces two big tools that are helpful to us and somewhat familiar from the C# world: namespaces/class definitions and the module pattern.

The module pattern allows us to provide an interface for the external world to interact with, but hide the code implementation of the module itself. This is done via closures and scoping of the code in the module. This allows us to introduce a form of encapsulation when using WinJS.

I will refer you to Douglas Crockford for the complete description of closures, but in brief Javascript allows a function to access the members of its containing function even after the containing function returns. Therefore the way to define scope and introduce private members is by using anonymous functions where the public members would have to be explicitly added. The module pattern as used in WinJS is a self-executing anonymous function that has parameters passed to it, but code is exposed publicly via defined namespace and classes.

The code pattern for the module itself is typically as follows:

(function (internalParam1, internalParam2) {
"use strict";
// private code goes here
})(globalParam1, globalParam2);

globalParam1 and globalParam2 are module dependencies passed in from the world outside the module as parameters. The module’s internal code resolves them as parameters to the internal function of the module internalParam1 and internalParam2.

We’ve now succeeded at hiding information away from prying eyes. Now we would like to tactfully expose it in a manner that would be familiar in its organization.

WinJS allows us to define namespaces by using the WinJS.Namespace.define() function. It accepts the name of the namespace and the namespace members are parameters. Namespace members in this case do not have to be only classes, we can also publicly expose variables and methods. Whether this is a powerful or a weak feature depends on whether or not you will use it or abuse it. In the code snippet below, I expose an array named Cars and function named FindCars() inside a namespace called Auto. Although there are no explicitly private members in Javascript, there is a convention to use underscore notation for members that are designated private through closures.

(function (internalParam1, internalParam2) {
"use strict";
var _cars = ["Studebaker", "Crosley", "Kaiser-Frazer"];
function _findCars() {
// private function code goes here
}
WinJS.Namespace.define("Auto", {
Cars: _cars,
FindCars: _findCars
});
})(globalParam1, globalParam2);

Now I can call the FindCars() method from outside the modules by the Auto namespace:
var carsResult = Auto.FindCars();

The WinJS.Namespace object also has a defineWithParent() method that allows you to pass in a pre-existing namespace as the first parameter to create a child namespace. For example, I could split my previous code snippet into two namespaces and nest the Cars array in a child namespace named ClassicCars. In this case, the code defining the Auto namespace is not even aware of the ClassicCars namespace at definition. This eerily reminds me of the obsolete Fortran come from statement and is also an opportunity to create spaghetti code if you’re not careful.

(function (internalParam1, internalParam2) {
"use strict";
var _cars = ["Studebaker", "Crosley", "Kaiser-Frazer"];
function _findCars() {
// private function code goes here
}
WinJS.Namespace.define("Auto", {
FindCars: _findCars()
});
WinJS.Namespace.defineWithParent(Auto, "ClassicCars", {
ClassicCars: _cars
});
})(globalParam1, globalParam2);

More commonly, we would like to define individual classes inside the namespace. This is possible through the WinJS.Class object as shown below:

(function (internalParam1, internalParam2) {
"use strict";
var _cars = ["Studebaker", "Crosley", "Kaiser-Frazer"];
function _findCars() {
// private function code goes here
}
function _getCost() {
// instance method code here
}
WinJS.Namespace.define("Auto", {
FindCars: _findCars()
});
WinJS.Namespace.defineWithParent(Auto, "ClassicCars", {
ClassicCars: _cars,
RepairBills: WinJS.Class.define(function(quantity) {
// RepairBills constructor code goes here
},
{
// instance members defined here
GetCost: _getCost
},
{
// static members defined here
repairBillTypes: [ "Scheduled", "Unscheduled" ]
})
});
})(globalParam1, globalParam2);

The define() function for the class is different from the namespace define, because it doesn’t allow you to pass in a name but instead has you pass in the construction function and two definitions for the instance and static members of the class.

Now that you’re comfortable with basic namespace and class declaration, it’s important to show that there are other ways to create classes since Javascript allows us to use the prototypes of other objects. The derive() function allows to create an object with a prototype of another object and takes in an additional parameter than the define() function pass in the object whose prototype will be used.

We’re going to conclude this post by using the mix() function in the WinJS.Class namespace to create a class called GasSpills using mixins. Mixins are objects that define a set of functionality. Think of them as a lonesome prototype, they allow you to quickly add functionality to an object. Our final code snippet define a GasSpills object with an empty constructor and binding functionality given to it by the WinJS.Binding.dynamicObservableMixin. The GasSpills object can now dynamically add bindable properties via the addProperty() method, bind actions to properties, etc. as defined by the mixin.

(function (internalParam1, internalParam2) {
"use strict";
var _cars = ["Studebaker", "Crosley", "Kaiser-Frazer"];
function _findCars() {
// function code
}
function _getCost() {
// instance method code here
}
WinJS.Namespace.define("Auto", {
FindCars: _findCars()
});
WinJS.Namespace.defineWithParent(Auto, "ClassicCars", {
ClassicCars: _cars,
RepairBills: WinJS.Class.define(function(quantity) {
// RepairBills constructor code goes here
},
{
// instance members defined here
GetCost: _getCost
},
{
// static members defined here
repairBillTypes: [ "Scheduled", "Unscheduled" ]
}),
GasSpills: WinJS.Class.mix(function () {
// GasSpills constructor code goes here
}, WinJS.Binding.dynamicObservableMixin)
});
})(globalParam1, globalParam2);