前面提到jQuery庫如何通過其中的jQuery.extend及jQuery.fn.extend去擴展自身的。第三篇給zChain.js添加瞭常用選擇器,但目前為止zChain.js仍然做不瞭任何事情。
jQuery的操作往往是分兩步
1,獲取元素集合(選擇器)
2,操作元素集合
而第二步操作元素集合的主要方法就是jQuery.each。查看源碼,我們發現jQuery.each及this.each分別調用瞭27次和31次。可見它是多麼的重要。
這篇將分析下jQuery.each及this.each方法。看看他們如何與jQuery.extend一起擴展jQuery庫。最後我會給zChain.js加上each方法。
部分源碼如下
view sourceprint?01 jQuery.fn = jQuery.prototype = {
02 …
03 // Execute a callback for every element in the matched set.
04 // (You can seed the arguments with an array of args, but this is
05 // only used internally.)
06 each: function( callback, args ) {
07 return jQuery.each( this, callback, args );
08 },
09 …
10 }
11
12 jQuery.extend({
13
14 …
15 // args is for internal usage only
16 each: function( object, callback, args ) {
17 var name, i = 0,
18 length = object.length,
19 isObj = length === undefined || jQuery.isFunction( object );
20
21 if ( args ) {
22 if ( isObj ) {
23 for ( name in object ) {
24 if ( callback.apply( object[ name ], args ) === false ) {
25 break;
26 }
27 }
28 } else {
29 for ( ; i < length; ) {
30 if ( callback.apply( object[ i++ ], args ) === false ) {
31 break;
32 }
33 }
34 }
35 // A special, fast, case for the most common use of each
36 } else {
37 if ( isObj ) {
38 for ( name in object ) {
39 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
40 break;
41 }
42 }
43 } else {
44 for ( ; i < length; ) {
45 if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
46 break;
47 }
48 }
49 }
50 }
51
52 return object;
53 },
54 …
55 });
以上可看出,
1,jQuery().each是直接掛在jQuery.prototype(jQuery.fn)上的,因此每個jQuery對象都包含each方法。
2,jQuery.each是通過jQuery.extend({})方式擴展的。前面已經說過,通過這種方式擴展的方法將掛在function jQuery上,即為jQuery類的靜態方法。
3,jQuery().each方法中隻有一句:return jQuery.each( this, callback, args )。即jQuery對象的each方法實現上其實就是調用jQuery靜態的jQuery.each。因此jQuery.each才是關鍵所在。
下面詳細分析jQuery.each,它有三個參數object, callback, args。
1,object可以為數組(Array),對象(Object),甚至是函數類型(Functoin);
2,callback是回調函數,類型為function;
3,args為jQuery庫自身使用,使用者不會用到該參數,這裡暫不討論該參數情況。
函數中第一句定義必要的變量
view sourceprint?1 var name, i = 0,
2 length = object.length,
3 isObj = length === undefined || jQuery.isFunction( object );
length=object.length很好理解,有三種情況length不為undefined
1, object為數組類型(Array)時,數組具有length屬性;
2, object為函數類型(Functoin)時,length為該函數定義的參數個數,如果該函數沒有定義參數,length為0;
3, 具有length屬性的object偽數組(如:arguments,HTMLCollection,NodeList等)。
變量isObj用來判斷是否是對象類型,有兩種情況為true:
1,變量length等於undefined,即所傳object沒有length屬性。
2,參數object為函數類型
這裡強調下object為jQuery對象。即當在$(xx).each時發生,這時會將this傳到$.each中。如:return jQuery.each( this, callback, args )。這裡第一個參數this即為jQuery對象,每個jQuery對象是具有length屬性的。
each中有以下兩個分支
1,如果isObj為true,則用for in語句去遍歷該對象,如果把每個迭代的對象看出鍵值對形式的話。callback中的this是值object[nam