是Backbone。*。扩展设置定义类的原型值?

时间:2014-05-10 00:05:15

标签: javascript backbone.js prototype

当使用带有集合的扩展时,模型是非主干方法的属性设置为定义的“类”的原型值吗?这意味着如果在类的一个实例中修改了这些属性,那么它们会针对类的所有实例进行更改吗?

我遇到了类似于以下问题。

例如:

var MyCollection = Backbone.Collection.extend({
options:
{
   someAttribute: null,
   anotherAttribute : null
},

url : function() 
{ 
    return this.options.someAttribute + "/" + this.options.anotherAttribute
});

var myCollectionInstance1 = new MyCollection();

_.extend(myCollectionInstance1.options,{
   someAttribute: "page1",
   anotherAttribute : "location1"});

var myCollectionInstance2 = new MyCollection();

_.extend(myCollectionInstance2.options,{
   someAttribute: "page1",
   anotherAttribute : "location2"});

// I call fetch here which will eventually run into my redefined url
// and now my url for this function is going to be 
// "page1/location2" instead of what I expect "page1/location1"
// I assume this is because the protoype is being changed in the above 
// of myCollectionInstance2.options
myCollectionInstance1.fetch();

如果是这种情况,那么将实例变量附加到集合的最佳方法是什么?

2 个答案:

答案 0 :(得分:4)

是的,extend的第一个参数中的所有内容都在原型中结束,因此由实例共享。可变属性(例如对象和数组)的常见解决方案是在initialize

中分配它们
var MyCollection = Backbone.Collection.extend({
    initialize: function(options) {
        this.options = {
            someAttribute: null,
            anotherAttribute: null
        };
        // The rest of the initialization goes here...
    }
});

如果您希望将它们保留在用于文档目的的位置,那么您可以在initialize_.clone

var MyCollection = Backbone.Collection.extend({
    default_options: {
        someAttribute: null,
        anotherAttribute: null
    },
    initialize: function(options) {
        this.options = _(this.default_options).clone();
        // The rest of the initialization goes here...
    }
});

请注意,_.clone仅执行浅层复制,因此如果this.options包含嵌入的数组或对象,您仍然可能会意外共享。

答案 1 :(得分:1)

问题出在你这样做的时候:

var MyCollection = Backbone.Collection.extend({
options:
{
   someAttribute: null,
   anotherAttribute : null
}

您正在创建一个与所有实例共享的对象{ someAttribute: null, anotherAttribute : null },当您这样做时:

_.extend(myCollectionInstance1.options,{ ...

您正在更新此共享对象。

您的问题的解决方案是您想要设置collection.options创建新对象:

myCollectionInstance1.options = {
   someAttribute: "page1",
   anotherAttribute : "location1"
};

...

myCollectionInstance2.options = {
   someAttribute: "page1",
   anotherAttribute : "location2"
};

这样每个集合都会拥有自己的对象。