Author: nuysoft/Gao Yun QQ: 47214707 EMail: nuysoft@gmail.com
After all, I am reading and writing at the same time. Please tell me if I am wrong, and we can communicate more and make progress together. This chapter is not finished yet, the PDF will be submitted when it is finished.
Preface:
I want to write systematically, but I will start with the interesting part first.
Recently, a reader has uploaded the PDF to Baidu Wenku. First of all, thank you for reprinting and spreading it. However, it is not good to have it and set a high wealth value to download it. I will sort it out and upload it to Wenku in the future. . Please be considerate.
3. Construct jQuery object
3.1 Source code structure
Let’s take a look at the overall structure first, and then decompose it:
(function( window, undefined ) {
var jQuery = (function() {
// Construct jQuery object
var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
}
// jQuery object prototype
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
// The selector has the following 7 branches:
// DOM element
// body (optimization)
// String: HTML tag, HTML string, #id, selector expression
// Function (as ready callback function)
// Finally returns a pseudo array
}
};
// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;
// Merge the content into the first parameter, and most subsequent functions will pass through this Function extension
// Most of the functions extended by jQuery.fn.extend will call the function of the same name extended by jQuery.extend
jQuery.extend = jQuery.fn.extend = function() {};
// Extend static methods on jQuery
jQuery.extend({
// ready bindReady
// isPlainObject isEmptyObject
// parseJSON parseXML
// globalEval
// each makeArray inArray merge grep map
// proxy
// access
// uaMatch
// sub
// browser
});
// here, jQuery The object construction is completed, and the following codes are all extensions of jQuery or jQuery objects
return jQuery;
})();
window.jQuery = window.$ = jQuery;
})(window );
l jQuery object is not created through new jQuery, but created through new jQuery.fn.init
var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
}
n The jQuery object is the jQuery.fn.init object
n If new jQeury() is executed, the generated jQuery object will be discarded, and finally the jQuery.fn.init object will be returned; therefore You can call jQuery(selector, context) directly. There is no need to use the new keyword
l. First execute jQuery.fn = jQuery.prototype, and then execute jQuery.fn.init.prototype = jQuery.fn. The merged code is as follows:
jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype
All methods mounted to jQuery.fn are equivalent to being mounted to jQuery.prototype, that is, mounted to the jQuery function (at the beginning jQuery = function(selector, context)), but in the end it is equivalent to mounting to jQuery.fn.init.prototype, which is equivalent to mounting to the object returned by the jQuery function at the beginning, that is, mounting to the object we finally use on the jQuery object.
This process is very convoluted, and the gold and jade are "lost" in the middle!
3.2 jQuery.fn.init
The function of jQuery.fn.init is to analyze the incoming selector parameters, perform various processing, and then generate jQuery objects.
Type (selector)
Processing method
DOM element
is packaged into a jQuery object and directly returns
body (optimization)
Reads
individual HTML tags from document.body
document.createElement
HTML string
document.createDocumentFragment
#id
document.getElementById
Selector expression
$(…).find
Function
Register to dom ready callback function
3.3 jQuery.extend = jQuery.fn.extend
// Merge the properties of two or more objects into the first object. Most of jQuery’s subsequent functions are extended through this function.
// Function extended through jQuery.fn.extend, Most of them will call the function of the same name extended by jQuery.extend
// If two or more objects are passed in, the properties of all objects will be added to the first object target
// If only one is passed in Object, add the object's properties to the jQuery object.
// In this way, we can add new methods to the jQuery namespace. Can be used to write jQuery plug-ins.
// If you don’t want to change the object passed in, you can pass in an empty object: $.extend({}, object1, object2);
// The default merge operation is not iterative, even if one of the target If the attribute is an object or attribute, it will be completely overwritten instead of merged
// The first parameter is true, it will be iteratively merged
// Attributes inherited from the object prototype will be copied
// undefined Values will not be copied
// For performance reasons, JavaScript's built-in type properties will not be merged
// jQuery.extend( target, [ object1 ], [ objectN ] )
// jQuery.extend ( [ deep ], target, object1, [ objectN ] )
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
// Handle a deep copy situation
// If One parameter is of type boolean, possibly a deep copy
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
// skip the boolean and the target
// Skip the boolean and target, starting from the 3rd one
i = 2;
}
// Handle case when target is a string or something ( possible in deep copy)
// target is neither an object nor a function, then it is forced to be an empty object
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
// extend jQuery itself if only one argument is passed
// If only one argument is passed, it is considered to be an extension of jQuery
if ( length === i ) {
target = this;
--i;
}
for ( ; i < length; i ) {
// Only deal with non-null/undefined values
//Only handle non-null parameters
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// Prevent never-ending loop
// Avoid circular references
if ( target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
// Deep copy and the value is a pure object or array, then recurse
if ( deep && copy && ( jQuery.isPlainObject( copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
// If copy is an array
if ( copyIsArray ) {
copyIsArray = false;
// clone is src Correction value
clone = src && jQuery.isArray(src) ? src : [];
// If the copy is an object
} else {
// clone is the correction value of src
clone = src && jQuery.isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
// Recursively call jQuery.extend
target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
// Cannot copy empty values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// Return the modified object
// Return the modified object
return target;
};
To be continued