jQuery: $.xxx()與$().xxx()中的$,為什么能同時(shí)支持兩種寫法?
網(wǎng)友解答: 其實(shí),這個(gè)問(wèn)題去看jquery源碼就能很清楚的知道了,從樓主的問(wèn)題說(shuō)明里面只是明白了jquery的方法擴(kuò)展方式,但并沒(méi)有真正理解其主要架構(gòu)方式;我下面所說(shuō)的都是基于2.0.3
其實(shí),這個(gè)問(wèn)題去看jquery源碼就能很清楚的知道了,從樓主的問(wèn)題說(shuō)明里面只是明白了jquery的方法擴(kuò)展方式,但并沒(méi)有真正理解其主要架構(gòu)方式;
我下面所說(shuō)的都是基于2.0.3版本jquery源碼進(jìn)行說(shuō)明,首先,描述中有幾個(gè)錯(cuò)誤需要指正下:
第一,在jquery中,$('xxx').xxxx()這種寫法,其實(shí)是通過(guò)jQuery.fn.extend({xxx: function() {}})的方式進(jìn)行方法綁定和擴(kuò)展的,而$.xxx()這種方式的方法是通過(guò)jQuery.extend({xxx: function() {}})的方式進(jìn)行方法綁定和擴(kuò)展的;如下圖,$.ajax通過(guò)下圖綁定:
而$('xxxx').attr()則通過(guò)下面方式:
第二,console.log(jQuery()) 其實(shí)是個(gè)對(duì)象,
console.log(jQuery('#test')),如果有此元素存在,看起來(lái)像數(shù)組,如下圖,其實(shí)也是對(duì)象,這種叫“類數(shù)組”;可以百度去看下類數(shù)組相關(guān)知識(shí);
好,下面開(kāi)始說(shuō)下樓主的兩個(gè)問(wèn)題,第一是extend的實(shí)現(xiàn)方法;第二是jquery為什么能同時(shí)支持$.xxx()與$().xxx()這兩種寫法;
第一,extend的實(shí)現(xiàn)方法;由于源碼較多,我在這兒就不直接展示出來(lái)了,有興趣可以去找到看看;其實(shí)簡(jiǎn)單講,extend主要用于對(duì)象的合并,如下圖;
但是從源碼可以看出,當(dāng)參數(shù)只有一個(gè)對(duì)象的時(shí)候,就是直接將傳入對(duì)象合并到調(diào)用的對(duì)象上 (即jquery或jquery.fn);
所以,當(dāng)調(diào)用jQuery.extend時(shí),就會(huì)將傳入的對(duì)象里面的方法合并寫入到j(luò)Query對(duì)象上面,就可以對(duì)其進(jìn)行擴(kuò)展; 同理,使用jQuery.fn.extend時(shí),就可以對(duì)jQuery.fn進(jìn)行擴(kuò)展;
第二,$.xxx()與$().xxx()兩種的區(qū)別;第一種$.xxx()其實(shí)是調(diào)用的jQuery對(duì)象上面的方法,也就是通過(guò)jQuery.extend進(jìn)行擴(kuò)展的方法;有人會(huì)說(shuō),jQuery是一個(gè)函數(shù),但是函數(shù)在js也是對(duì)象,也可以向其添加屬性和方法;而第二種$().xxx()則是調(diào)用的jQuery.fn對(duì)象上面的方法,也就是通過(guò)jQuery.fn.extend進(jìn)行擴(kuò)展的方法;
第一種通過(guò)jQuery.extend進(jìn)行擴(kuò)展的屬性和方法是直接寫入jQuery對(duì)象,所以也就可以直接通過(guò)$.xxx()的方式調(diào)用,這個(gè)很容易理解;
第二種,通過(guò)jQuery.fn.extend進(jìn)行擴(kuò)展的方法和屬性為何能夠通過(guò)$().xxx()進(jìn)行調(diào)用呢;這個(gè)就要從jQuery的整個(gè)架構(gòu)來(lái)說(shuō);當(dāng)執(zhí)行$()時(shí),訪問(wèn)了下圖代碼:可以看出,其實(shí)是實(shí)例化了一個(gè)jQuery.fn.init的對(duì)象;在這我們就不再討論jQuery.fn.init里面具體干了什么,但可以通過(guò)源碼可以看出,其最終執(zhí)行了“return this”,也就是返回了jQuery.fn.init的實(shí)例對(duì)象;那如何通過(guò)$()可以訪問(wèn)到j(luò)Query.fn上面的屬性和方法呢?就是通過(guò)下圖這句代碼:
它將jQuery.fn賦給了jQuery.fn.init.prototype,所以,jQuery.fn.init的實(shí)例對(duì)象也就可以直接訪問(wèn)jQuery.fn上面的方法和屬性了;所以,當(dāng)你通過(guò)$().xxx()時(shí),其實(shí)訪問(wèn)了jQuery.fn.xxx()方法;