Domanda

I'm a big fan of Backbone, but recently have come across some bizarre behavior with Backbone's extend. I call it bizarre probably because of a combination of misunderstanding the intention, and not understanding the deep nitty gritty of how javascript works. Long story short, modifying a property of any instance gets reset to the default when re-instantiating the object, modifying a sub property will change it for all future instances. I would love any insight into the matter.

Here is some code using Backbone's extend:

var myObj = function () {
    this.a = true;
};

myObj.extend = extend; //the backbone version, link provided at bottom

//the pattern used throughout backbone
var myExtension = myObj.extend({
    b: "hello"
});

var instance1 = new myExtension();
instance1.b = "goodbye";

var instance2 = new myExtension();
console.log(instance2.b); //logs hello!!

var myBadExtension = myObj.extend({
    b: {
        c: "hello"
    }
});

var bad1 = new myBadExtension();
bad1.b.c = "goodbye";

var bad2 = new myBadExtension();
console.log(bad2.b.c); //!!! logs "goodbye" !?!?!?!

Any and all help is greatly appreciated.

Link to backbone extend.

È stato utile?

Soluzione

Yes, because bad2.b and bad1.b is the same object, coming from their shared prototype. To avoid this, you should assign b a value in the initialize method.

var myBadExtension = myObj.extend({
    initialize: function() {
      this.b = {
        c: "hello"
      };
    }
});

It won't matter if a property is primitive (IOW not an object or an array), but I think it's more common to initialize primitives in the same way.

Given you are not using backbone's built-in classes, this might have a better chance of working.

var myBadExtension = myObj.extend({
  constructor: function() {        
    myObj.apply(this, arguments);

    this.b = {
      c: "hello"
    };
  }
});
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top