Summary of the implementation code of jquery constructor_jquery
Obviously, the implementation to achieve this step is quite complicated. This implementation is its init method, the real constructor of jQuery. Its functions are also upgraded with the version upgrade, and it is getting longer and longer.
Version 1.3 released on 2009-01-13
init: function( selector, context ) {
// Make sure that a selection was provided
selector = selector || document;
// Process node parameters and add attributes directly to the new instance
if ( selector.nodeType ) {
this[0] = selector;
this.length = 1;
this.context = selector;
return this;
}
// Processing string parameters
if ( typeof selector === "string" ) {
// Determine whether it is an HTML fragment or an ID
var match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
// If it is an HTML fragment, convert an array constructed from nodes
if ( match[1] )
selector = jQuery.clean( [ match[1] ], context );
// If it is an ID, search for this element, and if found, put it into an empty array
else {
var elem = document.getElementById( match[3] ) ;
// Make sure an element was located
if ( elem ){
// Deal with the bug of confusion between ID and NAME in IE and Opera
if ( elem.id != match[3] )
return jQuery().find( selector );
var ret = jQuery( elem );
ret.context = document;
ret.selector = selector;
return ret;
}
selector = [];
}
} else
//Use Sizzle to process other CSS expressions, generate instances and return
return jQuery( context ).find( selector );
// Process function parameters, directly domReady
} else if ( jQuery.isFunction( selector ) )
return jQuery( document ).ready( selector );
// Process jQuery object parameters, simple Assign its two properties to the new instance
if ( selector.selector && selector.context ) {
this.selector = selector.selector;
this.context = selector.context;
}
//Convert the node arrays obtained above and use the setArray method to turn them into instance elements
return this.setArray(jQuery.makeArray(selector));
},
Version 1.32 released on 2009-02-19
init: function( selector, context ) {
// Make sure that a selection was provided
selector = selector || document;
// Process node parameters and add attributes directly to the new instance
if ( selector.nodeType ) {
this[0] = selector;
this.length = 1;
this.context = selector;
return this;
}
//Processing characters String parameter
if ( typeof selector === "string" ) {
//Determine whether it is an HTML fragment or an ID
var match = quickExpr.exec( selector );
if ( match && ( match[1] || !context) ) {
// If it is an HTML fragment, convert an array constructed from nodes
if ( match[1] )
selector = jQuery.clean( [ match[ 1] ], context );
else {
var elem = document.getElementById( match[3] );
// If it is an ID, search for this element, and if found, put it into an empty array
if ( elem && elem.id != match[3] )
return jQuery().find( selector );
//Some optimizations have been made here for version 1.3, making it more concise
var ret = jQuery( elem || [] );
ret.context = document;
ret.selector = selector;
return ret;
}
} else
//Use Sizzle Process other CSS expressions, generate instances and return
return jQuery( context ).find( selector );
// Process function parameters and perform domReady operations
} else if ( jQuery.isFunction( selector ) )
return jQuery( document ).ready( selector );
//Process the jQuery object parameters and simply assign its two properties to the new instance
if ( selector.selector && selector.context ) {
this.selector = selector.selector;
this.context = selector.context;
}
//Here are some extensions to version 1.3, allowing the transfer of element collections (HTMLCollection) and nodes Collection (NodeList),
//The element array may be converted by us using a string, or it may be passed in directly by the user
return this.setArray(jQuery.isArray( selector ) ? selector : jQuery.makeArray (selector));
},
Version 1.4 released on 2010-01-13
init: function( selector, context ) {
var match, elem, ret, doc;
//Handle blank string, null, undefined parameters (newly added), return a very pure Instance of
if ( !selector ) {
return this;
}
// Process node parameters and directly add attributes to the new instance
if ( selector.nodeType ) {
this.context = this[0] = selector;//Optimized writing
this.length = 1;
return this;
}
//Processing string parameters
if ( typeof selector === "string" ) {
// Determine whether it is an HTML fragment or an ID
match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
//If it is an HTML fragment
if ( match[1] ) {
//Get the document object
doc = (context ? context.ownerDocument || context : document);
// If it is a single tag, directly use document.createElement to create this node and put it into the array
ret = rsingleTag.exec( selector );
if ( ret ) {
//If followed by Pure JS object, add corresponding attributes or styles to this node
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery. fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
/ /Change buildFragment to generate node collection (NodeList)
ret = buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret .fragment).childNodes;
}
} else {
// If it is an ID, search for this element, and if found, put it into an empty array
elem = document.getElementById( match[2] );
if ( elem ) {
// Deal with the bug of confusion between ID and NAME in IE and Opera
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
//Some optimizations have also been done here. It turns out that it is stupid to generate another jQuery instance
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
// If the character is a very simple label selector, there is basically no need to go Sizzle route, getElementsByTagName directly, very good optimization
} else if ( !context && /^w $/.test( selector ) ) {
this.selector = selector;
this.context = document;
selector = document.getElementsByTagName( selector );
// If the second parameter does not exist or is a jQuery object, then use it or rootjQuery to call find to find the target node (take the Sizzle route)
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector );
// HANDLE: $(expr, context)
// (which is just equivalent to : $(context).find(expr)
} else {
//If the second parameter has been specified as an element node, convert it to a jQuery object, take the Sizzle route
return jQuery( context ). find( selector );
}
// Process function parameters directly domReady
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
//Handle the jQuery object parameters and simply assign its two properties to the new instance
if (selector.selector !== undefined) {
this.selector = selector.selector;
this .context = selector.context;
}
//Some modifications have been made here, because makeArray can accept the second parameter (can be an array or array-like, which is equivalent to a merge operation)
return jQuery.isArray( selector ) ?
this.setArray( selector ) ://Use push method internally to quickly turn an ordinary object into an array-like object
jQuery.makeArray( selector, this );
} , <🎜> >The code is as follows:
init: function( selector, context ) {
var match, elem, ret, doc;
// Handle blank string, null, undefined parameters
if ( !selector ) {
return this;
}
// Process node parameters
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1 ;
return this;
}
// Process body parameters (new)
if ( selector === "body" && !context ) {
this.context = document;
this[0] = document.body;
this.selector = "body";
this.length = 1;
return this;
}
// Processing string parameters , divided into seven situations:
//①Single label, with object attribute package---> jQuery.merge
//②Single label, without object attribute package---> attr jQuery.merge
//③Complex HTML fragment---> buildFragment jQuery.merge
//④ID selector, which is different from the ID of the found element---> getElementById Sizzle pushStack
//⑤ID selection Device, the same as the ID of the found element ---> getElementById simple attribute addition
//⑥ tag selector ---> getElementsByTagName jQuery.merge
///⑦ other CSS expressions ---> ; Sizzle pushStack
if ( typeof selector === "string" ) {
match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
if ( match[1] ) {
doc = (context ? context.ownerDocument || context : document);
ret = rsingleTag.exec( selector );
if ( ret ) {
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
ret = buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
}
return jQuery.merge( this, selector );
} else {
elem = document.getElementById( match[2] );
if ( elem ) {
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
} else if ( !context && /^w $/.test( selector ) ) {
this.selector = selector;
this.context = document;
selector = document. getElementsByTagName( selector );
return jQuery.merge( this, selector );
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector );
} else {
return jQuery( context ).find( selector );
}
// Process function parameters directly domReady
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
//Processing jQuery object parameters
if (selector.selector !== undefined) {
this.selector = selector.selector;
this.context = selector.context;
}
//Whether it is an array or an array-like (such as NodeList), use jQuery.makeArray to add new elements to the instance
return jQuery.makeArray( selector, this );
},
Attached are the makeArray method and merge method. The merge method is so amazing.
makeArray: function( array, results) {
var ret = results || [];
if ( array ! = null ) {
// The window, strings (and functions) also have 'length'
// The extra typeof function check is to prevent crashes
// in Safari 2 (See: #3039)
if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
push.call( ret, array );
} else {
jQuery.merge( ret, array );
}
}
return ret;
},
merge : function( first, second ) {
var i = first.length, j = 0;
if ( typeof second.length === "number" ) {
for ( var l = second.length ; j < l; j ) {
first[ i ] = second[ j ];
}
} else {
while ( second[j] !== undefined ) {
first[ i ] = second[ j ];
}
}
first.length = i;
return first;
},
2011-01 Version 1.5 released on -23 has little change in the init method from 1.42: only two changes have been made:
//1.42
- ret = buildFragment( [ match[1] ], [ doc ] );
- selector = (ret.cacheable ? ret.fragment. cloneNode(true) : ret.fragment).childNodes;
//1.5
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? jQuery .clone(ret.fragment) : ret.fragment).childNodes;
//1.42
- return jQuery( context ).find( selector );
//1.5
return this.constructor( context ).find( selector );//The purpose is not to generate new instances
Jquery 1.6 released on 2011-05-02 has not changed much, except for a stricter judgment on HTML fragments:
// Are we dealing with HTML string or an ID?
if ( selector.charAt(0) === "<" && selector. charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];
} else {
match = quickExpr.exec( selector );
}
In general, the structure of jQuery The instrument has been made very perfect, and it has basically reached the point where "nothing can be changed". But to ensure its efficient operation, we also need some knowledge of selectors and understanding of the operation of the buildFragment method, because these two are too commonly used, but they are also the most performance-consuming.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Article discusses creating, publishing, and maintaining JavaScript libraries, focusing on planning, development, testing, documentation, and promotion strategies.

The article discusses strategies for optimizing JavaScript performance in browsers, focusing on reducing execution time and minimizing impact on page load speed.

Frequently Asked Questions and Solutions for Front-end Thermal Paper Ticket Printing In Front-end Development, Ticket Printing is a common requirement. However, many developers are implementing...

The article discusses effective JavaScript debugging using browser developer tools, focusing on setting breakpoints, using the console, and analyzing performance.

The article explains how to use source maps to debug minified JavaScript by mapping it back to the original code. It discusses enabling source maps, setting breakpoints, and using tools like Chrome DevTools and Webpack.

This tutorial will explain how to create pie, ring, and bubble charts using Chart.js. Previously, we have learned four chart types of Chart.js: line chart and bar chart (tutorial 2), as well as radar chart and polar region chart (tutorial 3). Create pie and ring charts Pie charts and ring charts are ideal for showing the proportions of a whole that is divided into different parts. For example, a pie chart can be used to show the percentage of male lions, female lions and young lions in a safari, or the percentage of votes that different candidates receive in the election. Pie charts are only suitable for comparing single parameters or datasets. It should be noted that the pie chart cannot draw entities with zero value because the angle of the fan in the pie chart depends on the numerical size of the data point. This means any entity with zero proportion

There is no absolute salary for Python and JavaScript developers, depending on skills and industry needs. 1. Python may be paid more in data science and machine learning. 2. JavaScript has great demand in front-end and full-stack development, and its salary is also considerable. 3. Influencing factors include experience, geographical location, company size and specific skills.

Once you have mastered the entry-level TypeScript tutorial, you should be able to write your own code in an IDE that supports TypeScript and compile it into JavaScript. This tutorial will dive into various data types in TypeScript. JavaScript has seven data types: Null, Undefined, Boolean, Number, String, Symbol (introduced by ES6) and Object. TypeScript defines more types on this basis, and this tutorial will cover all of them in detail. Null data type Like JavaScript, null in TypeScript
