我相信我在backbone.js有一个很好的背景,但我有一个我不明白的问题。
假设我们有这两种观点:
BaseView = Backbone.View.extend({
foo: {},
initialize: function(options) {
this.render();
},
render: function() {
// ...
}
});
PageView = BaseView.extend({
render: function() {
this.foo.bar = 23;
}
});
如果我们在两个视图中检查属性'foo',显然它将是一个空对象:
> BaseView.prototype.foo
Object {}
> PageView.prototype.foo
Object {}
但是如果我们创建一个PageView实例,BaseView的'foo'属性将会改变。怎么可能?
> page = new PageView()
> page.foo
Object {foo: 23}
> BaseView.prototype.foo
Object {foo: 23}
[编辑]
实际上,这是一个普遍的OOP问题。在python:
class A(object):
foo = {}
class B(A):
def __init__(self):
self.foo['bar'] = 23
>>> print A.foo
{}
>>> b = B()
>>> print A.foo
{'bar': 23}
答案 0 :(得分:2)
执行此操作时:
BaseView = Backbone.View.extend({
foo: {},
//...
});
foo: { }
附加到BaseView
原型。这意味着BaseView
的所有实例以及任何BaseView
“子类”的所有实例共享该确切对象。所以这个:
var BaseView = Backbone.View.extend({
foo: {},
//...
});
var PageView = BaseView.extend({
//...
});
var bv = new BaseView;
var pv = new PageView;
数据看起来真的像这样:
bv.foo -->--+-->-- BaseView.prototype.foo -->-- { }
|
pv.foo -->--/
因此,如果您使用pv.foo
之类的内容更改pv.foo.x = y
,那么您实际上正在更改BaseView.prototype.foo
,这与bv.foo
的对象相同;当然,如果您pv.foo = something_else
,那么您已更改了引用,bv.foo
和pv.foo
将不再引用相同的基础对象。您只有一个具有多个引用的基础对象。
当您实例化或扩展BaseView
或PageView
时,没有复制(既不浅也不深),您只是共享对基础对象的单个引用。
如果您希望foo
是特定于实例的(就像您几乎经常那样),请在构造函数中进行设置:
var BaseView = Backbone.View.extend({
initialize: function() {
this.foo = { };
//...
},
//...
});
当然,initialize
方法不会自行链接,因此如果您的PageView
需要一个方法,则必须自行完成:
var PageView = BaseView.extend({
initialize: function() {
BaseView.prototype.initialize.apply(this, arguments);
// Whatever else you need done...
},
//...
});
演示:http://jsfiddle.net/ambiguous/4duQ5/
另外,你真的应该说var BaseView
而不仅仅是BaseView
,没有var
意味着你正在创建一个全局,你可能不想这样做。< / p>