在什么情况下默认需要是一个函数?

时间:2014-07-31 13:01:19

标签: javascript backbone.js

我从查看localtodos应用开始,可以看到此代码使其成为一个功能。我不知道如何做出这个选择。我的假设是函数中的代码不会被运行,直到您调用函数而不是对象文字将被立即解释。

以下是用例:

var FavoritesRow = Backbone.Model.extend({
    Name: 'FavoritesRow',
    defaults: function () {
        return {
            url: "http://www.google.com",
            title: "google",
            favicon: "http://www.google.com/favicon.ico",
            tag: "search"
        };
    }
});

但是我应该遵循哪些规则/规则?

2 个答案:

答案 0 :(得分:4)

来自fine manual on model.defaults

  

请记住,在JavaScript中,对象是通过引用传递的,所以如果   如果将对象包含为默认值,则将在所有对象之间共享   实例。相反,将默认值定义为函数。

比较

var M = Backbone.Model.extend({
    defaults: {
        obj: {}
    }
});

var m1 = new M();
var m2 = new M();
console.log(m1.get('obj') === m2.get('obj'));
// ==> outputs true

http://jsfiddle.net/nikoshr/6ctZ2/

var M = Backbone.Model.extend({
    defaults: function() {
        return {
            obj: {}
        };
    }
});

var m1 = new M();
var m2 = new M();
console.log(m1.get('obj') === m2.get('obj'));
// ==> outputs false

http://jsfiddle.net/nikoshr/6ctZ2/1/

使用函数可以定义默认数组或对象,而无需在类的所有实例上共享它们。

答案 1 :(得分:0)

如果符合以下条件,您应该使用以下功能:

a)您需要访问this实例
b)在构建返回结果时需要执行条件逻辑 c)您不希望在所有实例中共享对象(尽管下面有替代方案)

如果您确实使用了一个对象,并且不希望它在类范围内共享,那么您可以在initialize中创建一个对象并使其成为一个函数:

this.defaults = {} // Now it is instance-scope

请注意,使用_.result并不总是会产生所需的this上下文。有时最好明确传递上下文,例如if (_.isFunction(this.x)) this.x.call(this)。在使用defaults _.result的情况下,您可能希望检查上下文确实是模型实例。