Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

explain backbone object and class creation pattern

I am moderate level javascript developer who's trying to understand how backbone library work internally and will deeply appreciate if someone help me to resolve some challenges.

so here is what i understand

basic definition of constructor function in Backbone is

Backbone.Model = function(attributes, options) { }

then they use general purpose extend method to add common features in our constructor's prototype.

_.extend(Backbone.Model.prototype, Backbone.Events, {...})

now until this part i know exactly what is happening and would be happy to instantiate new object though following code

var user = new Backbone.Model() 

and this is the part i am finding challenging

ofcourse it's not the way we instantiate a object in Backbone but we use extend method

var Users = Backbone.Model.extend({});
var user = new Users()

and in backbone code

Backbone.Model.extend = extend;

var extend = function(protoProps, classProps) {
        var child = inherits(this, protoProps, classProps);
        child.extend = this.extend;
        return child;
};

var inherits = function(parent, protoProps, staticProps) {
    var child;
    if (protoProps && protoProps.hasOwnProperty('constructor')) {
        child = protoProps.constructor;
    } else {
        child = function() {
            return parent.apply(this, arguments);
        };
    }
    _.extend(child, parent);
    ctor.prototype = parent.prototype;
    child.prototype = new ctor();
    if (protoProps) _.extend(child.prototype, protoProps);
    if (staticProps) _.extend(child, staticProps);
    child.prototype.constructor = child;
    child.__super__ = parent.prototype;
    return child;
};

please explain me what is happening inside inherit function and what is the benefit of extend method approach

like image 626
nitesh sharma Avatar asked Aug 16 '12 13:08

nitesh sharma


People also ask

What is backbone in programming?

Backbone. js is a model view controller (MVC) Web application framework that provides structure to JavaScript-heavy applications. This is done by supplying models with custom events and key-value binding, views using declarative event handling and collections with a rich application programming interface (API).

What is a model backbone?

Model. Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control. You extend Backbone.

Is backbone a MVC?

Backbone is a JavaScript MVC library and that's a key difference. In the JavaScript MVC context, a framework usually means that you need to configure your code to get things done.


1 Answers

Underscore's extend function merges the members (functions and properties) from the second argument into the first. For example:

var reciever = { 
    name: "Jonny",
    age: 29
};

var supplier: {
    languages: [ "javascript", "actionscript" ];
    sayHi: function () { 
        console.log("Hi, name name is " + this.name);
    }
};

_.extend(receiver, supplier);

After executing the above code, the receiver object will have been augmented (modified) and now look like this:

/*
    {
        age: 29,
        languages: [ "javascript", "actionscript" ],
        name: "Jonny",
        sayHi: <<function>>
    }
*/
console.dir(receiver);

Note that the supplier object remains unmodified and the receiver object gains all the properties and functions from the supplier. This process is commonly referred to as a mixin and is used to avoid having to redeclare functions (as part of a wider programming principle know an DRY - Don't Repeat Yourself).

Now as for Backbone's Model.extend function, it acts as a factory method to return you a Constructor Function which can be used to create new instances of your model with the internal inherits function doing the bulk of the work. The inherits function takes the mixin concept one step further an creates an inheritance chain between the supplied object and a parent (in this particular case, the Backbone.Model object).

var child;
if (protoProps && protoProps.hasOwnProperty('constructor')) {
    child = protoProps.constructor;
} else {
    child = function() {
        return parent.apply(this, arguments);
    };
}

This first block of code is trying to find a constructor function inside the supplied object hash; if one isn't present then it creates a new Constructor function for you which automatically passes the supplied arguments to Backbone.Model's own constructor function instead.

_.extend(child, parent);

Next we call underscore's extend method to mixin all the properties and functions from the supplied hash of properties and functions into the constructor function; this ensures that each instance you create has it's own data (eg: properties are not static and shared across all instances that you create).

ctor.prototype = parent.prototype;
child.prototype = new ctor();
if (protoProps) _.extend(child.prototype, protoProps);
if (staticProps) _.extend(child, staticProps);
child.prototype.constructor = child;
child.__super__ = parent.prototype;

This final block is the most exciting and creates a relationship between the freshly created Constructor function's prototype and the parent (Backbone.Model) object's prototype. By doing this, all new instances returned by the Constructor will contain the usual backbone Model methods (ie: get and set) as they are resolved from the prototype chain. If you want to learn more about this particular block of code, Douglas Crockford's article on Prototypal inheritance is a great place to start.

The point of this approach is that it lets you supply a hash of properties and function which the resulting Constructor function will use as a blueprint, for example:

var Person = Backbone.Model.extend({
    name: "Jon Doe",
    sayHi: function () { 
        console.log("Hi, my name is " + this.get("name"));
    }
});

Now each Person object you instantiate will have both a name property and a sayHi function, eg:

var dave = new Person();
dave.sayHi();   // "Hi, my name is Jon Doe"

dave.set("name", "Dave");
dave.sayHi();   // "Hi, my name is Dave"

// You can also supply properties when invoking the constructor.
var jimmy = new Person({ name: "Jimmy" });
jimmy.sayHi();  // "Hi, my name is Jimmy"
like image 73
JonnyReeves Avatar answered Sep 24 '22 03:09

JonnyReeves