先来了解几个jQuery方法:
<li></li>
<li></li>
<li></li>
$("li") -> this -> jQuery对象 -> { 0 : "li", 1 : "li", 2 : "li", length : 3 }
$("<li>aaa") 的效果跟 $("<li>")的效果是一样的。
然后来看一下init方法,也就是新建jQuery对象调用的方法:
jQuery.fn = jQuery.prototype = {
jquery: core_version, //jQuery的版本
constructor:jQuery, //修正constructor的指向,不写这个的话,constructor会指向Object,因此你重写了JQuery的prototype。
//新建一个构造函数时,会自动在构造函数的prototype对象中新添constructor属性(指向构造函数)。但是为了防止原型对象的覆盖,比如:Person.prototype = {};这时里面的constructor指向会出问题,需要修正,Person.prototype = { constructor: Person}
init:function(selector,context,rootjQuery){
var match,elem;
if(!selector){ //处理这种情况:$(""), $(null), $(undefined), $(false)
return this;
}
     if ( typeof selector === "string" ) {
			      if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
				        // $("<li>")  ->   match = [ null, "<li>", null ];
        // $("<li>1</li><li>2</li>")  ->   match = [ null, "<li>1</li><li>2</li>", null ];
				        match = [ null, selector, null ];
} else {
// 此正则rquickExpr匹配后,会出现以下几种情况:
// 1. match = null; $(".box"), $("div"), $("#div1 div.box")
// 2. match = ["#div1",null,"div1"]; $("#div1")
// 3. match = ["<li>aaa","<li>",null]; $("<li>aaa")
				        match = rquickExpr.exec( selector );
			      }
			      // $("#div1")通过id匹配元素,是在document中执行,不会传入context,所以context为空,因此进入if语句
			      if ( match && (match[1] || !context) ) {
				        if ( match[1] ) {   // $("<li>"), $("<li>aaa"),$("<li>1</li><li>2</li>")
          //context就是document,因为创建元素只能在document中执行。但是页面里面有iframe时,iframe中的document与页面的document不同,所以$("<li>",document)有第二个参数。一般用不上。
					          context = context instanceof jQuery ? context[0] : context;
//$("<li>",$(document)),得到原生的document。
					          jQuery.merge( this, jQuery.parseHTML(match[1],context && context.nodeType ? context.ownerDocument || context : document,
						true
					          ) );
//parseHTML方法:第一个参数传入标签字符串"<li>",第二个参数传入执行上下文document,第三个参数true代表可以新建script标签"<script><\/script>"(script前面的反斜杠需要转义,其他标签不需要),false代表不能。返回值是一个数组:$("<li>") -> ["li"], $("<li>1</li><li>2</li>") ->["li","li"]
//merge方法是把数组转换成jQuery对象:["li"] -> {0:"li",length:1} ;["li","li"] -> {0:"li",1:"li",length:2}
          rsingleTag匹配单标签的,$("<li>"),$("<li></li>")
					          if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
            //$("<li>",{title:"hi",html:"abcd"})  针对这种情况的,context 为json对象。
						            for ( match in context ) {
							              //如果属性是jQuery方法,就执行方法
							              if ( jQuery.isFunction( this[ match ] ) ) {
								                this[ match ]( context[ match ] );
							              
							              } else {
                //如果不是方法,就设置属性。
								                this.attr( match, context[ match ] );
							              }
						            }
					          }
return this;
				         
				        } 
        else {
					          elem = document.getElementById( match[2] );
					          // Blackberry 4.6:elem存在,但是页面上没有,所以添加了elem.parentNode,如果都满足,则elem一定存在页面上。
					          
					          if ( elem && elem.parentNode ) {
						            this.length = 1;
						            this[0] = elem;
					          }
					          this.context = document;
					          this.selector = selector;    //"#div"
					          return this;
				        }
			     
			      } 
      else if ( !context || context.jquery ) {
				          return ( context || rootjQuery ).find( selector );  //rootjQuery  = $(document)
// 处理这种$(expr, context),context是否是jQuery对象(context.jquery存在就是jQuery对象),会转换成$(context).find(expr)
			          //或者$(expr),会转换成$(document).find(expr)
			      } 
      else {   //如果context存在,但是不是jQuery对象,就执行
				          return this.constructor( context ).find( selector );   //新建jQuery对象,并调用find方法
			      }       
}
    else if ( selector.nodeType ) {       //如果是dom节点,比如:$(document)  
			          this.context = this[0] = selector;
			          this.length = 1;
			          return this;
}
    else if ( jQuery.isFunction( selector ) ) {     //文档加载有两种方式:$(function(){});$(document).ready(function(){});
			          return rootjQuery.ready( selector );
		    }
		    if ( selector.selector !== undefined ) {      //$($("#div1")),当传入jQuery对象时
			        this.selector = selector.selector;
			        this.context = selector.context;
		    }
return jQuery.makeArray( selector, this ); //传入数组和json对象时,比如:$([]),$({})
//makeArray把selector(类数组)转换成数组(外部使用),当传入第二个参数时(内部使用),就会转换成jQuery对象的形式。
},
length:0, //匹配到的元素的长度,默认为0.
......
};
加油!
原文:http://www.cnblogs.com/chaojidan/p/4136291.html