Inizialization of Backbone models and variables passed as reference

Posted July 4th, 2014 with 3 Comments

There are some apparently strange behaviours when working with Backbone models and properties.
Try this

var MyClass = Backbone.Model.extend({
  counter: {
    value: 1
  },
  getCounter: function() {
    return this.counter.value;
  },
  incCounter: function() {
    return this.counter.value += 1;
  }
});

var myClass1 = new MyClass();
var myClass2 =  new MyClass();

myClass1.getCounter(); // = 1
myClass1.incCounter(); // = 2
myClass1.getCounter(); // = 2, everything is fine so far
myClass2.getCounter(); // = 2 WTF!

Javascript is a dynamic language, the class above is extended at runtime from the Backbone model class, in particular the property counter is set to an hash with just the key “value”. The point is that hashes (like arrays) are passed by reference, so MyClass in the first line is extended with a reference to that hash and the method incCounter() basically increments every time the same hash even in different instances of the class.

This can easily be solved with a proper initialization method

var MyClass = Backbone.Model.extend({
  initialize: function() {
    this.counter = {
      value: 1
    };
  },
  getCounter: function() {
    return this.counter.value;
  },
  incCounter: function() {
    return this.counter.value += 1;
  }
});

Initialize a mixin in Backbone

Posted June 29th, 2014 with 2 Comments

Sometimes is useful to extend a class with a mixin rather than keeping deriving a subclass to add functionalities (Mixin). A mixin could be useful also to keep your class thin.
In Backbone this is quite easy

MyApp.Models.MyClass = Backbone.Model.extend({
  myMethod: function() {
    // do something
  }
});
MyApp.Mixins.MyMixin = {
  myMixinMethod: function() {
    return this.myMixinProperty;
  },
  myMixinProperty: 42
};

// extend the original class with the mixin
_.extend(MyApp.Models.MyClass.prototype, MyApp.Mixins.MyMixin);

// now my class has the new methods
var myClass = new MyApp.Models.MyClass();
myClass.myMixinMethod(); // 42

Then it may happens that we need to initialise the mixin, for example to setup some variables (in this example the initial value of the property is a simple number but this could lead to some problem in case the property is a variable passed by reference). The temptation is to call the initialize method of the mixin right in the extended class

MyApp.Mixins.MyMixin = {
  initializeMyMixin: function() {
    this.myMixinProperty = 42;
  },
  myMixinMethod: function() {
    return this.myMixinProperty;
  },
  myMixinProperty: null
};
MyApp.Models.MyClass = Backbone.Model.extend({
  initialize: function() {
    this.initializeMyMixin();
  }
});

But this is not a good practice since the extended class now depends on the mixin class. One big advantage of the mixin is that we can add the some methods to different classes without having to derive a subclass from each of them, a kind of simple multiple inheritance.
This works if the mixin is loosely coupled and my general rule of thumb is “if a method refers to something in the mixin, it must be in the mixin”.
We can solve it with a little bit of conventions and meta programming

MyApp.Models.MyClass = Backbone.Model.extend({
  initialize: function()
    var _this = this;
    _(_.functions(this)).each(function(func) {
      if (func.match(/^initialize[A-Za-z0-9]+$/)) {
        _this[func].apply(_this, arguments);
      }
    });
  },
  myMethod: function() {
    // do something
  }
});

Basically the initialize method of the Backbone class to be extended searches for methods like initialize* and execute them. With this convention we saved our loosely coupling (if we remove, add or change our mixin, nothing changes in the class to be extended).

Are you a compulsive reloader?

Posted July 16th, 2013 with No Comments

Several months ago I started working on Appcelerator Titanium, mainly in Javascript, the same language as the previous position but with a little difference: the IDE now takes 1-2 minutes to compile while on the web re-starting the project is just a matter of hitting the reload button.
I realized that I was compulsively hitting that button even for small changes.
When re-starting the project is a cost in terms of time – like in Titanium (consider the compilation and the time needed to navigate to the right feature) – it’s mandatory to write more code between reloads.
It turned out that now I write better code.
How many lines of code do you write on average between a reload?

  • Categories

  • Tags

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2 other subscribers

  • Follow me on Twitter