I spent a lot of time trying to catch a bug in my app. Eventually I set apart this piece of code which behavior seems very strange to me.
var Model = Backbone.Model.extend({
myProperty: []
});
var one = new Model();
var two = new Model();
one.myProperty.push(1);
console.log(two.myProperty); //1!!
What's the reason behind it? Why it acts so? How to avoid this type of bugs in code?
Inheritance in JavaScript is prototypical - objects can refer directly to properties higher up in the prototype chain.
In your example, one
and two
both share a common prototype, and do not provide their own values for myProperty
so they both refer directly to Model.protoype.myProperty
.
You should create new myProperty
array for each model you instantiate. Model.initialize
is the idiomatic place for this kind of initialisation - overriding constructor
is unnecessarily complex.
var Model = Backbone.Model.extend({
initialize: function() {
this.myProperty = [];
}
});
Alternatively you could make myProperty
as an attribute of the model:
var Model = Backbone.Model.extend({
defaults: function() {
return {
myProperty: []
}
}
});
It is important to note that defaults
is a function - if you were to use a simple object you would encounter the same shared reference issue.
Actually its because myProperty
is an array, and as you know arrays will be stored by reference. Just to test consider the following code:
var Model = Backbone.Model.extend({
myProperty: [],
messege: ''
});
var one = new Model();
var two = new Model();
one.messege = 'One!';
two.messege = 'Two!';
console.log(one.messege ); // 'One!'
console.log(two.messege ); // 'Two!'
An alternative around this could be:
var Model = Backbone.Model.extend({
constructor: function() {
this.myProperty = [];
Backbone.Model.apply(this);
}
});
var one = new Model();
one.myProperty.push(1);
var two = new Model();
console.log(two.myProperty); // []
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With