Skip to content

Latest commit

 

History

History
182 lines (133 loc) · 4.89 KB

README.md

File metadata and controls

182 lines (133 loc) · 4.89 KB

Underclass: a class mixin for underscore

Underclass is a mixin for Underscore that provides some syntactic sugar for declaring classes in JavaScript. It borrows some ideas from CoffeeScript, Python, PrototypeJS, and AngularJS.

Basically, it takes a look at the name of the arguments of your class methods and does things for you.

So something like this:

var Person = function (name, surname) {
    this.name = name;
    this.surname = surname;
};

Person.prototype.say = function (something) {
    alert(this.name + " " + this.surname + " says : " + something);
};

var Pirate = function (name, surname) {
    this.name = name;
    this.surname = surname;
};

Pirate.prototype = new Person();

Pirate.prototype.say = function(something){
    Person.prototype.say.apply(this, arguments);
    alert("... YIARR!!");
}

Turns into something like this:

var Person = _.class({
    initialize: function($name, $surname){},
    say: function(){
        alert(this.name + " " + this.surname + " says : " + something);
    }
});

var Pirate = _.class(Person, {
    initialize: function($name, $surname){},
    say: function(_super, something){
        _super(something);
        alert("... YIARR!!");
    }
});

Defining classes

class _.class([baseClass,] definition)

  • baseClass: Class to inherit from.
  • definition: An object containing the class methods. Class constructor can be specified in the 'initialize' key.

Special arguments in class constructor

Auto-properties: arguments beginning with $

Every argument in a class constructor that begins with a $ is automatically asigned to the class instance upon initialization.

var Person = _.class({
    initialize: function($name, $surname){
        /*
            no need to do this:

            this.name = name;
            this.surname = surname;
       */
    }
});

var morgan = new Person("Morgan", "Freeman");

console.log(morgan.name, morgan.surname) // --> 'Morgan', 'Freeman'

Object auto-properties: arguments beginning with $$ ( double dollar )

An argument begininng with $$ is assumed to be an object of properties, and each of its properties will be assigned to the class instance upon initialization.

This is useful when you have an object as a single argument instead of several ones, as this enhances readibilty when instantiating the object.

An example:

var Rectangle = _.class({
    initialize: function($x, $y, $width, $height){}
});

var r = new Rectangle(200,150,50,75); // wat?
var Rectangle = _.class({
    initialize: function($$properties){}
});

var r = new Rectangle({
    x: 200,
    y: 150,
    width: 50,
    height: 75
});

Special arguments in methods

There are two special arguments when defining methods: self and _super. Underclass will look for them and make stuff available for you through this special arguments, but wraps the exposed method in a function so you don't have to care about them when calling methods.

This special arguments have to be placed at the beginning of your method definition. These combinations are possible:

    function(self, ...){ ... }
    function(self, _super, ...){ ... }
    function(_super, ...){ ... }

_super argument

If you override one of its superclass's methods, you can invoke the overridden method through argument _super.

var Person = _.class({
    initialize: function($name, $surname){},
    says: function(){
        alert(this.name + " " + this.surname + " says : " + something);
    }
});

var Pirate = _.class(Person, {
    initialize: function($name, $surname){},
    say: function(_super, something){
        //_super is a reference to Person#say
        _super(something);
        alert("... YIARR!!");
    }
});

self argument

self is a reference to the class instance. Using self instead of this prevents you from having to type the infamous var that = this, binding functions, and other stuff.

var Person = _.class({
    initialize: function($name, $surname){},
    say: function(){
        alert(this.name + " " + this.surname + " says : " + something);
    },
    repeat: function(self, n, something){
        _(n).times(function(){
            self.say(something);
        });
    }
});

var repetitiveGuy = new Person("Jimmy", "McPerson");
repetitiveGuy.repeat(10, "Hey man!");

Inspiration ( borrowed/shamelessly stolen ideas )