我在Backbone遇到了一些奇怪的事情:
普通父类的所有子类似乎都与其兄弟姐妹一起获得“引用”属性...... !!
检查这个简单的测试用例:
var MyParentClass = Backbone.View.extend({
items:['foo'],
initialize: function() {
}
});
var MyFirstChildrenClass = MyParentClass.extend({
initialize: function() {
MyFirstChildrenClass.__super__.initialize.apply(this, arguments);
console.warn('MyFirstChildrenClass::initalize()');
this.items.push('bar');
}
});
var MySecondChildrenClass = MyParentClass.extend({
initialize: function() {
MySecondChildrenClass.__super__.initialize.apply(this, arguments);
console.warn('MySecondChildrenClass::initalize()');
console.warn(this.items); // expecting [foo] & getting [foo,bar] !
}
});
var firstInstance = new MyFirstChildrenClass();
var secondInstance = new MySecondChildrenClass();
答案 0 :(得分:8)
这是由JavaScript中对象文字的评估引起的。这一行:
items:['foo'],
立即计算数组,父类型/子类型都保存对同一对象的引用。
所有Backbone对象都使用对象文字扩展,以创建新类型。对象文字是关键:值对,其中键始终是文字键,一旦JavaScript解析器命中该行,就会计算值。因此,您将获得父类中数组['foo']
的单个引用。对象在JavaScript中引用,每个子类都包含对同一数组的引用。
解决此问题的最简单方法是将items
分配给返回数组的函数(在您的情况下看起来不是一个好的选项)或者在父类的构造函数中分配数组(或初始化方法,如果你想):
Backbone.View.extend({
constructor: function(){
Backbone.View.prototype.constructor.apply(this, arguments);
this.items = ['foo'];
}
});
关于对象文字和值的冗长讨论(在jQuery的上下文中,但这里适用相同的原则),请参阅我的博客文章:http://lostechies.com/derickbailey/2011/11/09/backbone-js-object-literals-views-events-jquery-and-el/
答案 1 :(得分:0)
items
当您将extend
调用添加到{{1}}调用时,新的主干“类”将成为类原型的一部分。
由于JavaScript使用Prototypal inheritance,这意味着该类的所有实例都可以使用共享。