(1)是ID选择器走的分支
(2)是多条件选择器走的分支
init: function( selector, context, rootjQuery ) { var match, elem, ret, doc; // 传入的selector为$(""), $(null), or $(undefined) if ( !selector ) { return this; } // 传入的selector是Dom元素,如document.getElementById("id") //注解1 if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; } if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; this.selector = selector; this.length = 1; return this; } // Handle HTML strings if ( typeof selector === "string" ) { // 传入"" 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 ); } // Verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { // HANDLE: $(html) -> $(array) if ( match[1] ) { context = context instanceof jQuery ? context[0] : context; doc = (context ? context.ownerDocument || context : document); // If a single string is passed in and it's a single tag ret = rsingleTag.exec( selector ); // " " to "tr" if ( ret ) { if ( jQuery.isPlainObject( context ) ) { selector = [ document.createElement( ret[1] ) ]; jQuery.fn.attr.call( selector, context, true ); //TODO } else { selector = [ doc.createElement( ret[1] ) ]; //createElement: "tr" --> " " } } else { //传入的selector中不包括Element,例如"fff" ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; //return NodeList[ ] } return jQuery.merge( this, selector ); // HANDLE: $("#id") } else { //(1)是ID选择器走的分支 elem = document.getElementById( match[2] ); if ( elem && elem.parentNode ) { // Handle the case where IE and Opera return items // by name instead of ID if ( elem.id !== match[2] ) { return rootjQuery.find( selector ); } // Otherwise, we inject the element directly into the jQuery object //(1)是ID选择器走的分支 this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { //(2)是多条件选择器走的分支 return (context || rootjQuery).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); } if (selector.selector !== undefined) { this.selector = selector.selector; this.context = selector.context; } return jQuery.makeArray( selector, this ); }
ID选择器和多条件选择器Demo:
$("#id"); $("#id1, #id2");
上面的例子在调用init创建就Query对象的时候,根本没有传递context,这里借用http://api.jquery.com/context/中的一句话来解释一下:The value of this property is typically equal to document, as this is the default context for jQuery objects if none is supplied. The context may differ if, for example, the object was created by searching within an