A Simple, Powerful, Lightweight Class for jQuery

jQuery’s functional programming style is downright elegant for manipulating the DOM. But it lacks the structure and code reuse patterns that professional scripters need. John Resig’s Simple Class inspired, jQuery.Class is a lightweight, but powerful class-like system that bridges the gap between jQuery’s functional programming style and Object Oriented Programming.

Features

  • Static and prototypal inheritance
  • Introspection
  • Namespaces
  • Setup and initialization methods
  • Easy callback creation

Download

jquery.class.js (minimized 2kb)

Demo

Extend a tabs widget to a history tabs widget demo.

Documentation

JavaScriptMVC’s Class docs.

Use

To create a monster class with static and prototype properties:

$.Class("Monster",
// static properties
{
  count: 0  
},
// prototype properties
{
  // constructor function
  init : function(name){
    //save the name
    this.name = name;

    this.energy = 10;

    //increment the static count
    this.Class.count++;
  }
})

//create a monster
var dragon = new Monster('dragon');

Inheritance

To extend (or inherit) from a class just call .extend on the class and provide the new name of your class and the static and prototype properties:

Monster("SeaMonster",{},{
  swim : function(distance){
    this.energy -= distance
  }
})

If you want to call an base class’s static or prototype method from the extended class:

SeaMonster("LochNessMonster",{},{
  swim : function(distance){
    this._super(distance/2);
  }
})

Notice how _super calls the base class’s method.

Introspection

You can access the full and short name of the class for groovy introspection techniques. The following uses the class’s name to change where the ajax request is sent:

$.Class("Model",{
  findAll : function(success){
    // use the class's name to find items
    $.get('/'+this.shortName.toLowerCase()+'s',
           success,
           'json')
  }
},{});

// create a task model
Model('Task')

//use it to make a request to /tasks
Task.findAll(function(tasks){
   alert(tasks.length);
})

Namespaces

Namespaces are a GREAT idea. It’s nice when code doesn’t clobber each other.

$.Class("MyCo.Project.MyClass");

MyCo.Project.MyClass.shortName //-> MyClass

MyCo.Project.MyClass.fullName //-> MyCo.Project.MyClass

Setup and Initialization Methods

When a class or instance of a class is created, setup and init methods are called on the class or instance. Setupis called before init and can be used to normalize arguments to init. Initis the class or instance’s constructor function. But unlike normal constructor functions, you don’t have to worry initialization code that will prevent further inheritance*.

The following makes sure all classes extending Controller will have their init function called with a jQuery element instead of an element:

$.Class("Controller",{
  setup : function(el){
    arguments[0] = jQuery(el);
    return arguments;
  }
})

// A dummy tabs class
Controller('Tabs',{
  init : function(el){
    this.element = el;
  }
})

var tab1 = new Tabs($("#foo")),
    tab2 = new Tabs($("#bar")[0]);

//call jQuery methods on element
tab1.element.show();
tab2.element.hide();

*You probably won’t need setup methods, but it’s cool if you need a lot of pre-processing for extending classes. The problem with normal constructor functions is that they typically need to be callable without arguments to be able to setup a correct prototype chain.

Easy Callback Creation

Similar to jQuery’s proxy, Class provides a static and prototype callback function that returns a callback that has ‘this’ or the context set to the Class or instance.

The following uses callback to return a function that will call the new task’s show method with ‘this’ set to the new task.

$.Class("Task",{
  init : function(name){
    this.name = name
  },
  get : function(){
    $.get('task',
         {name:this.name},
         this.callback('show'),
         'text')
  },
  show : function(instructions){
    alert(this.name+instructions)
  }
})

new Task("dishes").get()

The callback function lets you curry arguments and even gets a little Aspect Oriented Program-ish and lets you chain multiple callbacks*:

$.Class("Task",{
  init : function(name){
    this.name = name
  },
  get : function(date, callback){
    $.get('task',
         {name:this.name},

         // call show, then callback, curry date
         this.callback(['show', callback], date),
         'text')
  },
  show : function(date, instructions){
    // return arguments for next function
    return [this.name, date, instructions]
  }
})

new Task("dishes").get(
  new Date(), 
  function(name, date, instructions){
    console.log(name, date, instructions);
  }
)

*Chaining callbacks is helpful when there are multiple processing steps before some final callback is called. It makes it so you don’t have to curry the final callback over and over again. ;

Conclusions

Use classes where appropriate. There has been some fun poked at classy-ing up jQuery. But there is an important difference between an API for modifying the DOM and a sortable-paginated-groupable grid.

jQuery lacks a clear and repeatable pattern for organizing code. It also lacks tools to extend and add functionality to existing widgets. This is to jQuery’s strength. It makes jQuery useful to everyone.

But, as code gets more complex and teams get bigger, the need for patterns and tools to bridge the jQuery to Object Oriented Architecture gap becomes unavoidable. We hope jQuery.Class can help.

Advertisements
By Rz Rasel Posted in jQuery

2 comments on “A Simple, Powerful, Lightweight Class for jQuery

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s