Reputation: 2651
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.
Upvotes: 1
Views: 78
Reputation: 8192
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"
};
}
});
Upvotes: 3