Ext: Backbone.js Source parsing: Extend, Backbone.view

Source: Internet
Author: User

Source: http://www.cnblogs.com/mxw09/archive/2012/07/06/2579329.htmlBackbone version: 0.9.2

1. Parsing Backbone.model (Collection | Router | View). Extend

(1). Find the definition of extend

Defining the Extend function
var extend = function (Protoprops, classprops) {
/*
Typically we create a model, view, and other object type in a Backbone.XXX.extend way, so here this represents Backbone.model, Backbone.view and other corresponding constructors (note: A similar overview following the unification of Backbone.view as a concrete example)
*/
var child = Inherits (this, Protoprops, classprops);
Child.extend = This.extend;
return child;
};
Set the Extend method of model, Collection, Router, and view to extend
Model.extend = Collection.extend = Router.extend = View.extend = Extend;

(2) Analysis inherits function source code

var ctor = function () {};
var inherits = function (parent, protoprops, Staticprops) {
var child;
Determines whether Protoprops is a prototype object (prototype), and if so, assigns a child to the constructor that the prototype object belongs to
if (protoprops && protoprops.hasownproperty (' constructor ')) {
Child = Protoprops.constructor;
} else {
Otherwise, a new constructor is assigned to child
Child = function () {
The Inherits function returns a constructor that we call this constructor with new child () (for example: Appview = Backbone.View.extend ({}), Var appview=new appview ();), So here's this point to our new instance (for example, Var appview=new appview (), then this points to Appview)
The operation of new Appview is actually Backbone.Model.apply (this,arguments), which means that when we instantiate Appview, we actually call Backbone.model.
Parent.apply (this, arguments);
};
}

Here the parent is in 1 of this, that is, Backbone.view,_extend is a function in Underscore.js, which is to set all properties and property values of the second and second subsequent parameters to the first parameter (_ Extend the specific implementation of this does not repeat, can see Underscore.js source code)
_.extend (child, parent);

ctor is a null-content constructor, where its prototype object is set to Backbone.View.prototype
Ctor.prototype = Parent.prototype;
Set the child's prototype object to an instance of ctor, Child.prototype.contructor point to ctor
Child.prototype = new ctor ();
Copies all properties of the second parameter of Backbone.View.extend (typically an object) to the Child.prototype
if (protoprops) _.extend (Child.prototype, protoprops);

Copies all properties of the third argument of Backbone.View.extend (typically an object) to child, that is, to set a static property or method for child
if (staticprops) _.extend (Child, Staticprops);

After Child.prototype=new ctor is executed, Child.prototype.constructor does not point to child, so you need to display the settings here
Child.prototype.constructor = child;

ECMAScript does not define __super__ This attribute, this should be backbone record child corresponding Super class
child.__super__ = Parent.prototype;

return child;
};

(3) Summarize the prototype object chain

New Custom View () belongs to class---child (user created constructor) prototype object--an instance of ctor (some of our custom functions and methods are set to this instance) prototype Object-- Backbon.View.prototype

2. Parsing Backbone.view
Example:

Appview = Backbone.View.extend ({});
var appview=new appview ({});

(1) First look at the source of Backbone.view:

var viewoptions = [' Model ', ' collection ', ' El ', ' id ', ' attributes ', ' className ', ' tagName '];
var View = Backbone.view = function (options) {
_.uniqueid is also a function in the Underscore.js, the function is that its internal through the closure of an integer variable, each call to this function integer variable will increment by 1, and then use the passed in prefix (where the prefix is view) Join integer variable to a string, return the string
This.cid = _.uniqueid (' view ');
Call Backbone.view.prototype._configure, which is to merge options with AppView.prototype.options, and set the property name with the value not equal to False to this (_ Configure is specified later)
This._configure (Options | | {});
Do some processing based on whether the This.el is assigned a value
This._ensureelement ();
Backbone.View.prototype.initialize is called as a method of this, and Backbone.View.prototype.initialize defaults to a function that has empty content. In general, we will define a initialize function in the options (in Appview=backbone.view.extend ({initialize: ...}) Defined here, is actually AppView.prototype.initialize) to cover Backbone.View.prototype.initialize
This.initialize.apply (this, arguments);
This.delegateevents ();
};

(2) The _configure function is simplified by me as follows:

_.extend (View.prototype, {
_configure:function (options) {
Here is an example of our custom view, which is Appview

Determine if this has the Options property, If there is a this.options and options are combined then assigned to the options, through the analysis of the Extend method derived from the prototype object chain we analyze that because this time is not yet instantiated and Backbon.View.prototype does not have this property, then this The options can only come from Appview.prototype (an instance of ctor), meaning the this.options here is in Backbone.View.extend ({options: ...}) , and the options is the first parameter of the Appview constructor
if (this.options) options = _.extend ({}, this.options, options);
Traverse Viewoptions, when Options[viewoptions[i]] has a value, assign it to this
for (var i = 0, L = viewoptions.length; i < L; i++) {
var attr = viewoptions[i];
if (options[attr]) this[attr] = options[attr];
}
this.options = options;
}
});

(3) Delegateevents code parsing

A regular that matches a string that is not delimited by a delimiter, such as a space, a newline, or a 2-segment string separated by a delimiter, such as a space, line break, and so on
var delegateeventsplitter =/^ (\s+) \s* (. *) $/;
Delegateevents:function (events) {
Determines whether the events property (which can make an object, or a function that returns an object) exists and returns if it does not exist
if (! ( Events | | (Events = GetValue (this, ' events ')))) Return
Remove this. $el bound event
This.undelegateevents ();
Traversal of all specified events
for (var key in events) {
Events[key] is either a function or a method name for the view
var method = Events[key];
if (!_.isfunction (method)) method = This[events[key]];
If no event is found for the function, then the remove is thrown
if (!method) throw new Error (' method ' + Events[key] + ' "does not exist ');
The event name is cut, for example, "click. Toggle" will be cut to match=[' click. Toggle ', ' click ', '. Toggle ']
var match = Key.match (delegateeventsplitter);
Set event name, and selector
var eventName = match[1], selector = match[2];
_.bind is the method of Underscore.js, where this method is called to get a function method, the inside of the function refers to an instance of our custom view, that is, Appview
Method = _.bind (method, this);
Add namespaces to events so that all different types of events can be removed at once through the namespace
EventName + = '. Delegateevents ' + this.cid;
The following uses jquery for event binding
Bind event to $el if the selector is an empty string
if (selector = = = ") {
this. $el. Bind (EventName, method);
} else {
Depending on the selector, the child binding event for this. $el
this. $el. Delegate (selector, eventName, method);
}
}
}
Attach the source code of Undelegateevents
Undelegateevents:function () {
Removes all events (removed by namespace) that are currently passed by this. Bind or this $el. Delegate bound with a namespace of '. Delegateevents ' + this.cid.
this. $el. Unbind ('. Delegateevents ' + this.cid);
}

Attach the source code of GetValue
var getValue = function (object, prop) {
if (! ( Object && Object[prop])) return null;
Return _.isfunction (Object[prop])? Object[prop] (): Object[prop];
};

(4) _.bind source code Analysis, simplify the following:

Funcproto = Function.prototype;
Nativebind = Funcproto.bind;
var arrayproto = Array.prototype;
var slice = Arrayproto.slice;
var ctor = function () {};
_.bind = function bind (func, context) {
var bound, args;
Determines whether the current browser implements the Function.prototype.bind method for ECMAScript 5.1, and if so, calls this method directly and returns a function
If returned here, the function argument list returned is: (Arguments[2],arguments[3],...), and the This in the function refers to the context
if (Func.bind = = = Nativebind && nativebind) return nativebind.apply (func, Slice.call (arguments, 1));
If Func is not a function, it returns
if (!_.isfunction (func)) throw new TypeError;
Get all parameters after the third and subsequent (that is, all parameters after getting the context)
args = Slice.call (arguments, 2);
return bound = function () {
If bound is not used as a constructor, a function is returned here
if (! ( This instanceof bound))
{
If returned here, then the function parameter list returned is: (Args[0],args[1],..., arguments[0],arguments[1],...), and the function inside this refers to the context
Note that args is a segment of the arguments that invokes the outer _.bind function (implemented with closures), and arguments is the parameter object that is referenced when the function returned here is called
Return func.apply (Context, Args.concat (Slice.call (arguments)));
}
ctor is a null-content constructor, where its prototype object is set to Func.prototype
Ctor.prototype = Func.prototype;
Instantiate a Ctor object
var self = new ctor;
After the above two lines of code are executed, a scope chain is constructed: Self belongs to class---ctor prototype Object---Func.prototype

Call the Func function to get a return object. The list of function arguments returned is: (Args[0],args[1],..., arguments[0],arguments[1],...), and this in the function refers to self
Note that args is a segment of the arguments that invokes the outer _.bind function (implemented with closures), and arguments is the parameter object that is referenced when the function returned here is called
var result = func.apply (self, args.concat (slice.call (arguments)));

The following code returns an object, noting that the object in the constructor is returned, and the objects referenced in the constructor are discarded

If result is a reference type (such as Object,array, etc.), the result is returned
if (Object (result) = = = result)
{
return result;
}
Otherwise, return self
return self;
};
};

(5) Function.prototype.bind method for ECMAScript 5.1

Function.prototype.bind (Thisarg [, Arg1 [, arg2, ...])

Function.prototype.bind returns a new function object that is bound to the Thisarg parameter. Essentially, this allows you to execute a function in a chain of other objects. Examples are as follows:
function locate () {
Console.log (this.location);
}
function Maru (location) {
this.location = location;
}
var kitty = new Maru ("cardboard box");
var Locatemaru = Locate.bind (kitty);
Locatemaru ();

Ext: Backbone.js Source parsing: Extend, Backbone.view

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.