Search code examples
javascriptbackbone.js

In what cases does defaults need to be a function?


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?


Solution

  • 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.