jQuery 源码分析3: jQuery.fn/ jQuery.prototype

 1 // 建立方法实例,提高方法访问的速度(避免在原型链上搜索)
 2 
 3 var deletedIds = [];
 4 var slice = deletedIds.slice;
 5 var concat = deletedIds.concat;
 6 var push = deletedIds.push;
 7 var indexOf = deletedIds.indexOf;
 8 var class2type = {};
 9 var toString = class2type.toString;
10 var hasOwn = class2type.hasOwnProperty;
11 var support = {};
12 
13  
14 
15 jQuery.fn = jQuery.prototype = {
16      // 保存目前jQuery版本号
17      jquery: version,
18      // 指向构造器
19      constructor: jQuery,
20 
21      // 初始化空的选择器
22      selector: "",
23 
24      // 初始化长度为0,及空的jQuery对象的length为0,可以此判断是否存在查找结果
25      length: 0,
26      // 转换成Array并返回
27      toArray: function() {
28           return slice.call( this );     // 使用了Array.slice     
29      },
30 
31      // num == 0 则返回所有元素
32 
33      // 如果 num < 0, 则返回第this.length + num个元素
34      get: function( num ) {
35           return num != null ?
36                // 返回一个元素
37                ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
38                // 返回全部元素
39                slice.call( this );
40      },
41 
42      // 将一个DOM元素集Array压入到jQuery栈
43 
44      // 该方法在find,parent,filter中被频繁使用
45 
46      // 通过创建prevObject,能够跟踪链式调用中上一个调用方法返回的元素集
47      pushStack: function( elems ) {
48            // 建立新的jQuery对象以保存新的元素集(将新元素集合并到其中)
49           var ret = jQuery.merge( this.constructor(), elems );
50            // 新jQuery对象中创建prevObject,引用原来的jQuery对象,更新新元素集的上下文
51           ret.prevObject = this;
52           ret.context = this.context;
53            // 返回新的元素集
54           return ret;
55      },
56 
57      // 每个元素都调用一次回调函数,参数已Array形式传递(内部调用时才使用)
58      each: function( callback, args ) {
59           return jQuery.each( this, callback, args );
60      },
61       // jQuery.map对this中的每个key重新用回调函数计算出新的值并返回
62 
63      // 将jQuery.map的返回结果添加到新的jQuery中并返回,新的jQuery以原有的元素为基础
64      map: function( callback ) {           return this.pushStack( jQuery.map(this, function( elem, i ) {
65                return callback.call( elem, i, elem );
66           }));
67      },
68       // 通过slice将"参数数组"截取并压栈
69      slice: function() {
70           return this.pushStack( slice.apply( this, arguments ) );
71      },
72       // 将第一个元素压栈并返回新的jQuery栈
73      first: function() {
74           return this.eq( 0 );
75      },
76       // 将最后一个元素压栈并返回新的jQuery栈
77      last: function() {
78           return this.eq( -1 );     // 实际上是 len - 1, 即最后一个元素
79      },
80       // 取this[i]并压栈,如果i < 0则取this[len + i],如果i > len, 压入空Array
81      eq: function( i ) {
82           var len = this.length,
83                j = +i + ( i < 0 ? len : 0 );           return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
84      },
85       // prevObject是通过pushStack创建的,通过end跟踪链式调用中上一个方法返回的DOM元素集
86      // end相当与一个出栈操作,通过end,能够返回到上一个链式调用方法的元素集,如
87 
88      // $().find('button').click(function(){alert(1)})     // 对find('button')返回的元素操作
89 
90      //             .end().click(function(){alert(2)})     // 返回到find('button')返回的元素,然后操作
91 
92      end: function() {
93           return this.prevObject || this.constructor(null);
94      },
95       // 内部调用, 引用Array方法
96      push: push,
97      sort: deletedIds.sort,
98      splice: deletedIds.splice
99 };

 

 
这里定义了一个重要的方法————jQuery.pushStack;它在find,filter,parent等方法中被频繁使用。通过创建prevObject记录上次链式调用时返回的元素集结果,以此能够实现对链式调用元素集的跟踪,利用jQuery.end来回溯到上一次调用的结果。
 


posted @ 2015-07-23 20:12  elcarim  阅读(330)  评论(0编辑  收藏  举报