I. reading guidance

Article as a form of learning notes, recording learning experience and knowledge of principles, if there is a mistake, welcome to correct.
This article starts with some simple jQuery source code to analyze where a framework starts and what js does at the bottom.
Understanding his design ideas, the overall architecture of jquery still relies on js, encapsulating its own methods on the basis of js, and understanding
 It is easier to understand some principles of js in the process of reading and designing.

Enumeration of Knowledge Points

  1. Anonymous self-executing functions and closed packages.
  2. prototype
  3. Data Type Detection
  4. this pointing
  5. Binding execution environment (call)
  6. Deep copy

3. Source code analysis

//1. Anonymous self-executing functions and closed packages form closure-protected variables that are not directly accessed and tampered with to ensure the integrity of the framework.
//Closure scopes also help cache variable values.
(function(root){
    //It's really necessary to understand that the actual content of instantiating a constructor is its prototype.
    var jQuery=function(){
        return new jQuery.prototype.init();
    }
    jQuery.fn=jQuery.prototype={
        init:function(){

        },
        toString:Object.prototype.toString,//You need to use toString on the Object prototype
        hasOwn:Object.prototype.hasOwnProperty,
        typeClass:{//toString returns the attributes of the current detected object as object keys
            '[object Boolean]' : 'boolean', 

            '[object Number]' : 'number', 

            '[object String]' : 'string', 

            '[object Function]' : 'function', 

            '[object Array]' : 'array', 

            '[object Date]' : 'date', 

            '[object RegExp]' : 'regExp', 

            '[object Object]' : 'object' 
        },
        //Here the call method replaces the toString execution environment on the Object prototype with that under obj because of the object's 
        //The toString method on prototype returns the variable type.
        //According to the rules of prototype chain, functions or arrays will have their own toString when they are instantiated.
        isObject:function(obj){
            return this.typeClass[this.toString.call(obj)]=='object';
        },
        isFunction(fun){
            return this.typeClass[this.toString.call(fun)]=='function';
        },
        type :function(obj) { //return type

            return obj == null ? String(obj) : this.typeClass[toString.call(obj)] || "object"; 
            
        }, 
        isWindow : function(obj) { //Judge whether it's window or not
            
            return obj && typeof obj === "object" && "setInterval" in obj; 
            
        }, 
        //Invoke type detection only if the isArray method is not supported
        isArray : Array.isArray || function(obj) { 
            
            return this.type(obj) === "array"; 
            
        }, 
        isPlainObject : function(obj) { 
            //Excluding the type nodeType that cannot be deeply copied cannot be a dom element or a window object
            if (!obj || this.type(obj) !== "object" || obj.nodeType || this.isWindow(obj)) { 
            
                return false; 
            
                } 
        
            if (obj.constructor && !this.hasOwn.call(obj, "constructor") 
            
                && !this.hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) { //Judge if there is a constructor, whether inherited inheritance is too deep to replicate
            
                    return false; 
            
                }
                var key; 
                //Judging whether an attribute is its own, if it is inherited from the prototype, then this
                //
                for (key in obj) { 
            
                   } 
            
                   return key === undefined || this.hasOwn.call(obj, key); 
        }
        
    }
    /** 
     * Consider why participation must be an object.
     * The object is a reference type when multiple parameters are passed in. When parameters are passed in, we change the value of the input parameter, which changes the value of the address to which the original object refers.
     * When a single parameter component expands, a method is passed in, and the property of the method as an object becomes a reference type, so that the inserted component points to the address of the incoming method.
     * 
     * */ 
    jQuery.fn.extend=jQuery.extend=function(){
        var target=arguments[0]||{};
        var option,key,deep,src, copy, copyIsArray, clone,
            length=arguments.length,
            deep = false,//Default shallow copy
            i=1;//Decide on the number of entries in the cycle
        if(typeof target==="boolean"){//Determine whether or not a deep copy is introduced
            deep=target;
            target=arguments[1]||{};//Transferred deep copy switch parameters move one bit backward
            i=2;//The third entry begins with the merged object
        }
        if(!jQuery.fn.isObject(target) && !jQuery.fn.isFunction(target)){
            target = {};
        };
        if(length === i){//When only one parameter is passed in
            target=this;//Point to the object that calls extension, that is, jQuery instance object jquery.prototype or jqery
            i--;//Let the following loop add the method to the object currently pointed to by this, but the teacher didn't write it.
        };
        for(;i<length;i++){   //Shallow copy
            if((option=arguments[i])){
                for(key in option){
                    src=target[key];
                    copy=option[key];
                    if ( target === copy ) {//The target object is equal to an attribute of the copied object, and there may be circular references within the object???
                        continue;
                    }
                    if ( deep && copy && ( jQuery.fn.isPlainObject(copy) || (copyIsArray = jQuery.fn.isArray(copy)) ) ) {
                        if ( copyIsArray ) {//If it's an array, copy the array with a numeric subscript as key
                          copyIsArray = false;
                          clone = src && jQuery.fn.isArray(src) ? src : [];
                        } else {
                          clone = src && jQuery.fn.isPlainObject(src) ? src : {};
                        }
                       target[ key ] = jQuery.fn.extend( deep, clone, copy );//Recursive call
                     } else if ( copy !== undefined ) {
                       target[ key ] = copy;
                  }
                }
            }
        }
        return target;
    }

    jQuery.fn.init.prototype=jQuery.fn;
    //Sharing prototype objects actually refers to jQuery.prototype attributes when instantiating jQuery.prototype.init
    //When you call yourself to instantiate your own attributes, you fall into a dead cycle. Shared prototypes can share their own prototypes with one of their own attributes.
    root.$=root.jQuery=jQuery;//Attributes mounted to global

})(this)//this points to the object that executes the current function and loads the framework under window s if it does.
//In a fixed scope, local use can be guaranteed.