Backbone.js继承的问题

时间:2013-05-26 19:14:35

标签: javascript oop backbone.js

我相信我在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}

1 个答案:

答案 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.foopv.foo将不再引用相同的基础对象。您只有一个具有多个引用的基础对象。

当您实例化或扩展BaseViewPageView时,没有复制(既不浅也不深),您只是共享对基础对象的单个引用。

如果您希望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>

相关问题