Jquery factory

The general structure of jquery

As mentioned in the last two articles, The core of Query is a jQuery factory. The code is as follows

Function (window, noGlobal) {var jQuery = function(selector, context) {// Define an internal jQuery. $return new jquery.fn.init (selector, context); $return new jquery.fn.init (selector, context); }; /* jQuery. Fn = jquery. prototype = {//... }; jQuery.extend = jQuery.fn.extend = function() { //... }; var init = jQuery.fn.init = function( selector, context, root ) { //... }; init.prototype = jQuery.fn; jQuery.extend({ //... }); jQuery.fn.extend({ //... }); if ( ! JQuery = window.$= jQuery; } return jQuery; }Copy the code

In fact, by far the hardest thing to understand is this:

var jQuery = function( selector, context ) {
        return new jQuery.fn.init( selector, context );
    };
Copy the code

How do you feel about giving your grandchild to your grandfather? Was it the chicken or the egg?

Actually, it should look like this:

Var jQuery = function(selector, context) {selector (contextselector, contextselector) {selector (contextselector, contextselector); };Copy the code

Okay, second, why new jquery.fn. Init (selector, context); Assign this instance to jQuery?

The reason is, new is for jQuery, so when you call jQuery, you don’t have to call new anymore.

function( window, noGlobal ) { var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); }; ... if ( ! noGlobal ) { window.jQuery = window.$ = jQuery; } return jQuery; }Copy the code

As you can see from the above code, jQuery is already a new object. So, when we use jQuery, there is no new step, just $. Or $(“).

Looking down, there are:

jQuery.fn = jQuery.prototype = {
        //...
    };
Copy the code

Why do I write it this way? What’s the mystery? Or is it all just about being pushy? It’s true that assigning fn prototype to fn is a shorthand rather than “prototype”.

Fourth doubt:

    jQuery.fn = jQuery.prototype = {
        //...
    };
    jQuery.extend = jQuery.fn.extend = function() {
        //...
    };
    jQuery.extend({
        //...
    });
    jQuery.fn.extend({
        //...
    });
Copy the code

How is jquery.extend different from jquery.fn.extend?

Of course not. The jquery.extend extension (as the name suggests) is for instances, while jquery.fn.extend is for prototypes. Extended instances, which are limited to instances; Extend the prototype, but benefit all instances. Extend the prototype to save memory. Wait, isn’t there only one instance of jQuery?

No,

var jQuery = function( selector, context ) {
        return new jQuery.fn.init( selector, context );
    };
Copy the code

JQuery has many instances, depending on the parameters. For example, $(” div “) and $(” #div1 “) are two different instances.

Doubt five:

    var init = jQuery.fn.init = function( selector, context, root ) {
        //...
    };
    init.prototype = jQuery.fn;
Copy the code

Why override the jQuery prototype (jquery.fn) over its grandson (jquery.fn.init)? Answer: because jquery.fn would not be used otherwise, a series of prototype extensions: jquery.fn.extend () would have been in vain. Why? Because

var jQuery = function( selector, context ) {
        return new jQuery.fn.init( selector, context );
    };
Copy the code

This means that when this function is actually executed, jQuery will be replaced by an instance of its grandchild, so extensions must be applied to the grandchild’s prototype at the definition stage. So, why not extend grandchild’s prototype directly, instead extend grandchild’s prototype, then overwrite grandchild’s prototype, and then construct grandchild’s instance and assign it to grandpa? That’s fucking tricky. All this messing around, maybe for brevity and a little readability? You see, the grandson’s name is Init.