Vishful thinking…

Moving away from the javascript module pattern

Posted in javascript by viswaug on March 2, 2011

A while ago I had written about using the javascript module pattern to organize code a little better. But off late, I have moved away from using the module pattern because of some reasons which i will outline below. But the pattern to use is really a matter of preference in my opinion. I have now gone back to basics and am using the javascript prototype pattern and have been loving it. Here is why i made the switch

  • the ‘this’ keyword in my class method means what I really expect/want it to mean
  • creating multiple instances of my class doesn’t consume more memory for creating more function instances since all instances use the functions on the prototype
  • the ‘instanceof’ operator can be used to determine if any object is an instance of the class

Here is a simple example illustrating how to create a class. The snippet below creates a class called ‘MyClass’ with the ‘getOption’, ‘calculatePay’, ‘getDisplayPay’ methods.

function MyClass(options) {//constructor
  this.options = options;
};

MyClass.prototype.getOption = function(name) {
  return this.options[name];
};

MyClass.prototype.calculatePay = function(hours) {
  return hours * this.options['hourlyRate'];
};

MyClass.prototype.getDisplayPay = function(hours) {
  return this.getOption('name') + " - " + this.calculatePay(hours);
};

To create an instance of the class above

var inst = new MyClass({‘name’ : ‘Jeff’, ‘hourlyRate’ : 1000});

Also, the following works too

inst.constructor === MyClass; //returns true

if( inst instanceof MyClass ) //evaluates to true

Pretty simple and sweet. Here are a couple of examples of classes written like above

g2kml

g2geojson

I am also using the standalone YUITest for unit testing javascript which doesn’t require the YUI framework which looks more attractive in YUI3. It was a very close call between YUITest and QUnit for the unit testing framework. I went with YUITest because it came with Selenium drivers

YUITest example for g2kml

YUITest example for g2geojson

Advertisement

5 Responses

Subscribe to comments with RSS.

  1. steve said, on March 2, 2011 at 4:11 am

    i’m always curious to know why people use array syntax on objects in javascript. and also curious why you didn’t consider jasmine for unit tests.

    • viswaug said, on March 2, 2011 at 12:22 pm

      Ha! Nice catch. I have been doing python for a couple of months now and that habit has sneaked into my javascript 🙂

      Thank You,
      Vish

  2. steve said, on March 2, 2011 at 4:15 am

    at least it got me to do http://jsperf.com/array-vs-object which says perf wise it doesn’t matter. just easier for me to type object syntax.

  3. DavidQ said, on April 4, 2011 at 6:17 pm

    interesting coding style. 🙂

  4. steve said, on May 22, 2014 at 2:27 pm

    IT depends. I always uses a singleton, unless it has to have multiple instances. It’s easy to change it from

    // Stage 1: Original design, which is a singleton because it doesn’t need multiple instances.
    var myObj = {
    getOption:function(){},
    calculatePay:function(){},
    getDisplayPay:function(){}
    }

    // Stage 2: Refactor = very easy to adapt old singleton pattern as an prototype object.
    var MyClass = function(){};
    MyClass.prototype = {
    getOption:function(){},
    calculatePay:function(){},
    getDisplayPay:function(){}
    }

    I don’t see the need to write each method in its own prototype declaration as it seems popular by everyone like below:

    MyClass.prototype.getOption = function(name) {
    return this.options[name];
    };

    MyClass.prototype.calculatePay = function(hours) {
    return hours * this.options[‘hourlyRate’];
    };

    MyClass.prototype.getDisplayPay = function(hours) {
    return this.getOption(‘name’) + ” – ” + this.calculatePay(hours);
    };

    You aren’t overwriting any existing prototype methods. This is a new class so just write it like this:

    MyClass.prototype = {
    getOption:function(name) {
    return this.options[name];
    },
    calculatePay: function(hours) {
    return hours * this.options[‘hourlyRate’];
    }
    getDisplayPay:function(hours) {
    return this.getOption(‘name’) + ” – ” + this.calculatePay(hours);
    }
    }


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 )

Facebook photo

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

Connecting to %s

%d bloggers like this: