jquery源码之JQ对象

(function(window, undefined) {
  //- 模块
  (96,283)  jQuery.fn :给JQ对象,添加一些方法和属性 
  //- 模块解析
  jQuery.fn = jQuery.prototype = {  // 添加实例属性和方法
    jquery :版本
    constructor :修正指向问题
    init() :初始化和参数管理
    selector :存储选择字符串
    length :this对象的长度
    toArray() :jq对象转原生数组,可将jq对象转成由原生对象组成的数组,即 {0: div, 1: div, 2: div} -> 原生[div, div, div]
    get() :jq对象转原生集合,可获取get指定的原生dom,$('div').get(1).innerHTML = '22222'; 
    pushStack() :jq对象的入栈,在源码中非常重要!
    each() :遍历集合,使用jq对象对工具方法:return jQuery.each();
    ready() :dom加载的接口,延迟对象的处理:jQuery.ready.promise().done( fn );
    slice() :集合截取,【return this.pushStack('截取对dom对象');】如:$('div').slice(1,3).css('background', 'red');
    first() :集合的第一项,return this.eq( 0 );
    last() :集合的最后一项,return this.eq( -1 );
    eq() :集合的制定项,return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
    map() :返回新集合,调用 this.pushStack() 和 工具方法 jQuery.map();
    end() :返回集合前一个状态,【return this.prevObject; 】如:$('div').pushStack( $('spsn') ).css('background', 'red').end().css('background', 'yellow');
    push() :core_push :将数组的push方法挂载到jq对象上,使得jq对象拥有该方法,供jq库内部使用
    sort() :[].sort :同上
    splice() :[].splice :同上
  }
})(window)
 
【知识点梳理】
1、关于constructor属性的指向原理
function Aaa(){};
js源码中,当一个函数 Aaa 创建完之后,会自动给他原型中(Aaa.prototype)添加属性 constructor,并将属性指向构造函数本身,即 Aaa.prototype.constructor = Aaa;
2、init函数处理的【5种情况】
  (1) $("") $(null) $(undefined) $(false)
  (2) $("#div") $(".box") $("div") $("#div div.box")
     $("<li>") $("<li>1</li><li>2</li>")
  (3) $(this) $(document)
  (4) $(function() {})
  (5) $( [] ) $( {} )
2.1、对于(2)的源码解析---init函数处理解析
【第一个if判断,if选择字符串,如(2)种情况】
if ("string") {
 
【第二个if判断:获取match用于后续if判断】
if () {
  // $("<li>") $("<li>1</li><li>2</li>")
  match = [null, '<li>', null];
  match = [null, '<li>1</li><li>2</li>', null];
} esle {
  // $("#div") $(".box") $("div") $("#div div.box")
  // $("<li>hello")
  match = null; // $(".box") $("div") $("#div div.box")
  match = ['#div1', null, 'div1']; // $("#div")
  match = ['<li>hello', '<li>', null]; // $("<li>hello")
}
【第三个if判断:创建标签和id选择器为真,class选择器,标签选择器和组合选择器为假】
if () {
  【第三个if嵌套if判断:创建标签为真,id选择器为假】
  if () { $("<li>") 处理;return this; } else { $("#div") 处理;return this; };
} else if ( !context || context.jquery ) {
  // 处理有原生的复杂选择器 or 没有上下文时
  $('ul', document).find('li');  >>转化为jq选择器>> jQuery(document).find('xx');   // find -> sizzle find最终调用sizzle
  $(document).find('ul li.box');  >>转化为jq选择器>> jQuery(document).find('xx');  // find -> sizzle
} else {
  // 处理jq对象的复杂选择器
  $('ul', $(document)).fint('li'); >>转化为jq选择器>> jQuery(document).find('xx');  // find -> sizzle
}
 
【第一个if判断,else if选择dom节点,如(3)种情况】
} else if (选择dom节点) {
  return this;
【第一个if判断,else if选择函数,如(4)种情况】
} else if (选择函数) {
  $(function(){ });
  $(document).ready(function(){ }); // dom加载是怎么做到的?
}
【与第一个if判断平级,另起一个if判断】
if () {
  // 处理如下方式的选择
  $( $('#div1') )  >>转化为jq选择器>> $('#div1)
}
【与第一个if判断平级,剩下的情况处理:数组,json】
return jQuery.makeArray( selector, this ); // makeArray(); 内部使用,传两个参数,可将数组转成json,符合this的格式的json;
 
 
 3、jq对于$('li')的源码解析

 

【小知识点梳理】
1、jquery的工具方法:构建库对最底层,实例方法:构建库更高一级的层次,很多实例方法通过调用工具方法实现?
2、jq实现的正负选择:( num < 0 ? this[ this.length + num ] : this[ num ] );
3、对“栈”对理解:先进后出,first push last unshift;
posted @ 2017-12-05 21:18  _watson  阅读(328)  评论(0编辑  收藏  举报