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
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).
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.
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.
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With