Reprint Aaron Blog----jQuery 2.0.3 Source Analysis Core-Overall architecture

Source: Internet
Author: User
Tags access properties prototype definition

JQuery 2.0.3 Source Analysis Core-Overall architecture

Reading an open source framework, the most wanted to learn is the idea of design and the implementation of the skills.

Not much nonsense, jquery so many years of analysis have been written rotten, long ago to read,

But these years are to do mobile end, has been Queen Zepto, recently took some time to sweep jquery again

I will not be scripted translation source, combined with their actual experience to read it together!

On GitHub the newest is jquery-master, added AMD specification, I will take the official newest 2.0.3 to prevail

Overall architecture

The core of the jquery framework is to match elements from an HTML document and perform operations on them,

For example:

$ (). Find (). CSS () $ (). Hide (). html (' ... '). Hide ().

At least 2 questions can be found from the above notation

1. How jquery objects are built

2. How the jquery method is invoked

Analysis One: No new construction of jquery

JavaScript is a functional language, functions can implement classes, and classes are the most basic concepts in object-oriented programming.

var aquery = function (selector, context) {        //constructor}aquery.prototype = {    //prototype    name:function () {}, age    : function () {}}var a = new Aquery (); A.name ();

This is a normal use, and it's obvious that jquery doesn't play this way.

jquery does not instantiate the jquery display using the new runner or call its function directly

According to the way jquery is described

$ (). Ready () $ (). Noconflict ()

To achieve this, then jquery will be treated as a class, then $ () should be an instance of the returned class to

So change the code:

Press CTRL + C to copy the code<textarea></textarea>Press CTRL + C to copy the code

Through new Aquery (), although the return is an instance, but also can see very obvious problem, dead loop!

So how do I return a correct instance?

Instances of this in JavaScript are only related to prototypes

The jquery class can then be used as a factory method to create an instance and put this method into a Jquery.prototye prototype.

var aquery = function (selector, context) {       return  aQuery.prototype.init ();} Aquery.prototype = {    init:function () {        return this;    }    Name:function () {},    age:function () {}}

When executing aquery () The returned instance:

It is obvious that aquery () returns an instance of the Aquery class, so this is actually an instance of the Aquery class that is pointed to in Init.

Here's the problem. The this point of Init is the Aquery class, and if the init function is also treated as a constructor, how does the internal this handle?

Press CTRL + C to copy the code<textarea></textarea>Press CTRL + C to copy the code

This makes a mistake, because this only points to the Aquery class, so you need to design a separate scope.

Processing of jquery framework-delimited scopes

jquery = function (selector, context) {        //The jquery object is actually just the Init constructor ' enhanced '        r Eturn New JQuery.fn.init (selector, context, rootjquery);    },

It is clear that the instance init function constructs a new Init instance object each time to separate this and avoid interaction confusion

So if it's not the same object, then there's definitely a new problem.

For example:

var aquery = function (selector, context) {       return  new AQuery.prototype.init ();} Aquery.prototype = {    init:function () {        this.age =        return this;    },    name:function () {}, age    : 20}//uncaught Typeerror:object [Object Object] has no method ' name ' Console.log (Aquery (). Name ())

Throws an error and cannot find this method, so it is clear that the new Init is separated from the jquery class

How do I access properties and methods on the jquery class prototype?

Is it possible to isolate scopes and use the scope of jquery prototype objects, and to access the prototype objects of jquery in the return instance?

Key points of implementation

Give the init function The JQuery prototype for later instantiationjQuery.fn.init.prototype = Jquery.fn;

Solve problems with prototype delivery, and pass the prototype of jquery to JQuery.prototype.init.prototype

In other words, jquery's prototype object overrides the Init constructor's prototype object

Because it is a reference pass, there is no need to worry about the performance of this circular reference

var aquery = function (selector, context) {       return  new AQuery.prototype.init ();} Aquery.prototype = {    init:function () {        return this;    },    name:function () {        return this.age    },< C9/>age:20}aquery.prototype.init.prototype = Aquery.prototype;console.log (Aquery (). Name ())//20

Baidu borrowed a picture of netizens, to facilitate direct understanding:

FN explained that in fact this FN has no special meaning, just jquery.prototype reference

Analysis Two: Chained calls

Handling of DOM chained calls:

1. Save JS Code.

2. The same object is returned, which can improve the efficiency of the Code

Cross-browser chained calls are implemented by simply extending the prototype method and using the return this form.

Use the Simple Factory mode under JS to specify the same instance for all operations on the same DOM object.

This is a very simple principle.

Aquery (). Init (). Name () decomposition a = Aquery (); A.init () A.name ()

To decompose the code, it is obvious that the basic condition of the chain is the existence of the instance, and the same

Aquery.prototype = {    init:function () {        return this;    },    name:function () {        return this    }}

So we're going to need a chained way to access this, because we're returning the current instance of this, and then we can access our own prototypes.

Aquery.init (). Name ()

Pros: Save code, improve code efficiency, and make your code look more elegant

The worst thing is that all of the object's methods return the object itself, meaning there is no return value, which is not necessarily appropriate in any environment.


JavaScript is a non-blocking language, so he is not blocking, but not blocking, so he needs to be driven by events, asynchronous to do some of the need to block the process of operation, so that the process is only synchronous chain, asynchronous chain jquery from the beginning of 1.5 introduced Promise, jquery.deferred later in the discussion.

Analysis Three: plug-in interface

The main framework of jquery is this, but according to the general designer's custom, if you want to add a property method for jquery or jquery prototype, also if you want to provide developers with the extension of the method, from the packaging point of view is not to provide an interface, The literal ability to understand is to extend the function rather than to look directly at modifying prototype. Friendly user interface,

JQuery supports its own extended properties, which provides an external interface, JQuery.fn.extend () to add methods to objects

As you can see from the source code of JQuery, Jquery.extend and jQuery.fn.extend are actually different references to the same method

Jquery.extend = JQuery.fn.extend = function () {
Jquery.extend extends the properties and methods of jquery itself jQuery.fn.extend the properties and methods of Jquery.fn.

With the Extend () function, you can easily and quickly extend functionality without destroying the prototype structure of jquery.

Jquery.extend = JQuery.fn.extend = function () {...}; This is even, that is, 2 points to the same function, how to achieve different functions? This is the power!

For FN and jquery are actually 2 different objects, which were previously narrated:

    • When Jquery.extend is called, this is a pointer to the jquery object (jquery is a function and an Object!). ), so here's the extension on jquery.
    • When JQuery.fn.extend is called, this points to the FN object, Jquery.fn and Jquery.prototype point to the same object, and the extended FN is the extended Jquery.prototype prototype object.
    • This adds to the prototype method, which is the object method. So the jquery API provides the above 2 extension functions.

The realization of Extend

Jquery.extend = JQuery.fn.extend = function () {var src, copyisarray, copy, name, options, clone, target = Argum Ents[0] | | {},//Common usage jquery.extend (obj1, Obj2), at which point the target is arguments[0] i = 1, length = Arguments.length, D    Eep = false; Handle a deep copy situation if (typeof target = = = "Boolean") {//If the first parameter is true, that is, Jquery.extend (true, OBJ1, OB J2);  The case of deep = target; At this point target is true target = arguments[1] | |    {};    Target change to obj1//Skip the Boolean and the target i = 2; }//Handle case when Target was a string or something (possible in deep copy) if (typeof target!== "Object" &&    amp;!jquery.isfunction (target)) {//Handle strange situations, such as jquery.extend (' Hello ', {nick: ' Casper}) ~ ~ target = {}; }//Extend JQuery itself if only one argument is passed if (length = = = i) {//handle this case jquery.extend (obj), or Jque  Ry.fn.extend (obj) target = this; Jquery.extend, this refers to the Jquery;jquerY.fn.extend, this refers to Jquery.fn-I.;  } for (; i < length; i++) {//-deal with non-null/undefined values if (options = arguments[I            ]) = null) {//For example Jquery.extend (Obj1, Obj2, Obj3, OJB4), options are Obj2, obj3 ...//Extend the Base object                for (name in options) {src = target[name];                copy = options[name];                Prevent never-ending loop if (target = = = copy) {//Prevent self-reference, do not repeat continue;                }//Recurse If we ' re merging plain objects or arrays//if it is a deep copy, and the copied property value itself is an object if (deep && copy && jquery.isplainobject (copy) | | (Copyisarray = Jquery.isarray (copy)))                        {if (Copyisarray) {//copied attribute value is array copyisarray = false; clone = src && jquery.isarray (src)?                    SRC: []; } else {The property value being copiedis a plainobject, for example {nick: ' casper '} clone = src && jquery.isplainobject (src)?                    src: {}; }//Never move original objects, clone them target[name] = Jquery.extend (deep, C  Lone, copy); Recursive ~//Don ' t bring in undefined values} else if (copy!== undefined) {//Shallow copy, and property value is not u                ndefined target[name] = copy; }}}}//Return the modified object return target;

Summarize:

    • A new JQuery.fn.init () is used to construct the prototype prototype object with the Init constructor.
    • By changing the direction of the Prorotype pointer, the new object also points to the JQuery class's prototype prototype
    • So the objects that have been built will continue to jquery.fn all the methods of the prototype definition.

Reprint Aaron Blog----jQuery 2.0.3 Source Analysis Core-Overall architecture

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.