Nested classes - nodirt/defineClass GitHub Wiki

Nested classes

When a monolithic method of a class gets too complex and you do not want to pollute the class with a bunch of new methods that are used only in one place, it is convenient to implement method's functionality as a nested class.

var Phone = defineClass({
    _super: Device,

    // define a nested class
    CellRadio: defineClass({
      signal: function () {
        return 5;
      }
    }),

    constructor: function (ram) {
        this._super(ram);

        // create an instance of the nested class as "new this.CellRadio()"
        this.radio = new this.CellRadio();
    },

    dial: function (number) {
        // check that the radio signal is strong enough
        if (this.radio.signal() < 2) {
            console.log("Signal is too weak:", this.radio.signal())
            return;
        }
        console.log("Dialing to " + number);
    }
});

Note that CellRadio class is instantiated as new this.CellRadio(). This is flexible because this.CellRadio can be overridden in a subclass.

Nested class overriding

Since CellRadio is a member of Phone, a class derived from Phone can override it:

var BadPhone = defineClass({
    _super: Phone,

    CellRadio: {
        signal: function () {
            return 1;
        }
    }
});

var phone = new BadPhone(1000);
phone.dial(123456); // Signal is too weak: 1

Since the CellRadio class is overridden in the BadPhone, it is unnecessary to change the way the radio object is created in the base class.

In the fact the above definition is just a syntax sugar and is equivalent to

var BadPhone = defineClass({
  _super: Phone,

  // override a nested class
  CellRadio: defineClass({
    _super: Phone.prototype.CellRadio,
    signal: function () {
      return 1;
    }
  })
});