Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js: Model inheritance causes shared data

I've been banging my head on this one for the last two days. For some reason backbone is sharing parent instance data across inherited child models. Heres an example:

var Base = Backbone.Model.extend({

  index : []

});

var Group = Base.extend({

  initialize : function() {
    this.index.push('from group');
  }

});


var User = Base.extend({

  initialize : function() {
    this.index.push('from user');
  }

});


var user = new User();
console.log(user.index); // ['from user']


var group = new Group();
console.log(group.index) // ['from user', 'from group']

What I'm looking for is:

console.log(user.index); // ['from user']
console.log(group.index) // ['from group']

Any insights?

Thanks! Matt

like image 602
Matt Avatar asked Apr 23 '12 00:04

Matt


2 Answers

What you are experiencing is essentially a byproduct of the way JS passes objects (or arrays) by reference and not by value. If you want index to be different for User and Group, simply instantiate it as an array in your initialize function.

var Base = Backbone.Model.extend({

initialize: function() {
  this.index = [];
}


});
like image 179
Skylar Anderson Avatar answered Oct 20 '22 00:10

Skylar Anderson


The index member is like a class variable in that it's in the prototype chain of Base and thus shared by all instances just as the methods it contains are also shared. Try switching the order of the instantiating User and Group. Now what does index contain? It's reverse right? That's because they are sharing everything the object passed to extend.

In order for it to be an instance variable you'll need to instantiate it in a constructor for Base, and have each subclass call that constructor from their respective constructors. Like:

var Base = Backbone.Model.extend({
    initialize: function() {
       this.index = [];
    }
});

var User = Base.extend({
    initialize: function() {
        Base.prototype.initialize.call( this );
        this.index.push('User');
    }
});

// repeat it for group.
like image 40
chubbsondubs Avatar answered Oct 20 '22 00:10

chubbsondubs