TonyTakeshi
TonyTakeshi

Reputation: 5929

BackboneJS - View class array variables retained after re-instantiation

I encounter a scenario/bug which I can't explain, as I have a Backbone View class with array variable, but the variable value persist even after I re-instantiate it. The backbone view has following setup:

var TestView = Backbone.View.extend({
    a:"",
    b:"",
    items:[],
    initialize:function(){

    },
    add:function(value){
        this.items.push(value);
    }
});

Here's how I instantiate the class:

this.formView = new TestView();
this.formView.add('halo');
this.formView.a = 'abc';

this.formView = new TestView();
this.formView.add('test');
this.formView.b = 'bcd';

console.log("a - " + this.formView.a);
console.log("b - " + this.formView.b);
console.log("items - ");
console.log(this.formView.items);
​   

Result:

a -  
b - bcd 
items -  ["halo", "test"] 

Surprisingly, the array variable 'items' persist and it shown both ['halo','test'] together. But not for the normal variables.

Here's the JsFiddle link.

It is solvable by clearing the array at initialize function.

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

But I would like to know is this a bug or I misunderstood something.

Upvotes: 3

Views: 582

Answers (1)

fguillen
fguillen

Reputation: 38802

Well, the issue is tricky but it has an explanation.

First of all is not good idea to define instance variables in a class context and this is what you are doing with this:

var TestView = Backbone.View.extend({
  a: "",
  b: "",
  items: []
});

This is one of the reasons Model.defaults exists. You rather should to this:

var TestView = Backbone.View.extend({
  initialize: function(){
    this.a = "";
    this.b = "";
    this.items = [];
  }
});

What is happening in your example code is that all the new references of TestView will share the same instances of String and Array. this is because changing the Array in one instance will reflect in the other instance.

The most tricky thing, and you was agile to observe, is that it looks like the sharing behavior is not happening with the Strings but in fact it is happening.

What is happening is that when you do this:

this.formView.a = 'abc';

You are not transforming the String instance but replacing it for a new one so the original String instance remains untouched.

I would like to offer an example of manipulating the String in one TestView instance and seeing the changes reflect in the other TestView instance but I don't found any JS String method that manipulates the String in-place.

Upvotes: 7

Related Questions