1

I started by looking at the localtodos app and can see that this code makes it a function. I don't know how to make this choice. My assumption is that the code in the function is not run untill you call the function unlike and object literal which will be interpreted immediately.

Here is the use case:

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"
        };
    }
});

But what rule / rules should I follow in general?

2 Answers2

4

From the fine manual on model.defaults:

Remember that in JavaScript, objects are passed by reference, so if you include an object as a default value, it will be shared among all instances. Instead, define defaults as a function.

Compare

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/

and

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/

Using a function will let you define default arrays or objects without sharing them on all instances of the class.

nikoshr
  • 32,926
  • 33
  • 91
  • 105
  • **shared** among all instances, not initialized with a new value as would be the case if you used a function – nikoshr Jul 31 '14 at 13:10
  • there is no new or old value there is just one value for a default. –  Jul 31 '14 at 13:18
  • I have added an example – nikoshr Jul 31 '14 at 13:18
  • so you only need to use a function in the case when your defaults are complex, that is they are reference types. If all my defaults are primitives, than I don't need to. Hence his example makes sense. Correct? –  Jul 31 '14 at 13:27
0

You should use functions if:

a) You need to access this instance
b) You need to do conditional logic when building your return result c) You don't want to share the object across all instances (though there is an alternative below)

If you do use an object and don't want it shared across class-scope you can make an object in initialize as well as making it a function:

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

Note that using _.result will not always result in the desired this context. Sometimes it's better to explicitly pass the context e.g. if (_.isFunction(this.x)) this.x.call(this). In the case of defaults _.result is used so you might want to check the context is indeed the model instance.

Dominic
  • 62,658
  • 20
  • 139
  • 163