質問

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.

役に立ちましたか?

解決

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"
    };
  }
});
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top