离开范围后,收集状态似乎仍然存在

时间:2012-02-25 19:45:54

标签: javascript jquery backbone.js underscore.js

我在backbone.js集合上有一些特殊属性。我想出了一个简单的例子来尝试和说明:

TestCollection = Backbone.Collection.extend({
    properties: {
        something: 'foo',
        other: 'bar'
    }
});

假设test是在网址#test被点击时调用的路由。它运行这种方法。

test: function(){
    var c = new TestCollection();
    console.log(c.properties.something);
    c.properties.something = 'changed';
},

如果我然后访问其他哈希,说#anythingelse,然后返回#test,则控制台仍会记录"changed",而不是"foo"的值。我需要在创建集合时“重置”状态。当我有一个局部变量时,为什么州会留下来?我尝试过像_.clone这样的东西尝试“备份”一些属性并在初始化函数中检索它们,但我还没有成功。我希望我只是完全误解了一些东西,并且有一个简单的解决方案。

1 个答案:

答案 0 :(得分:2)

所有的TestCollection实例最终都会共享完全相同的properties值,因为没有进行深度复制;事实上,正如下面ggozad所述,由于properties附加到原型而非实例,因此根本没有复制。例如,这将在您的控制台中为您提供三个pancakes,因为所有三个实例在{something: '...'}中共享完全相同的properties对象:

TestCollection = Backbone.Collection.extend({
    properties: {
        something: 'foo'
    },
    m: function(x) {
        this.properties.something = x;
    }
});
var t1 = new TestCollection();
var t2 = new TestCollection();

t1.m('pancakes');
console.log(t1.properties.something);
console.log(t2.properties.something);

var t3 = new TestCollection();
console.log(t3.properties.something);

演示:http://jsfiddle.net/ambiguous/hBeHU/

摆脱这种困境的一个简单方法就是将properties移到收藏集initialize中:

TestCollection = Backbone.Collection.extend({
    initialize: function() {
        this.properties = {
            something: 'foo'
        };
    },
    m: function(x) {
        this.properties.something = x;
    }
});

如果您使用此版本的TestCollection,那么您的控制台中将获得一个pancakes和两个foo

演示:http://jsfiddle.net/ambiguous/GywKF/