其實,這個問題去看jquery原始碼就能很清楚的知道了,從樓主的問題說明裡面只是明白了jquery的方法擴充套件方式,但並沒有真正理解其主要架構方式;
我下面所說的都是基於2.0.3版本jquery原始碼進行說明,首先,描述中有幾個錯誤需要指正下:
第一,在jquery中,$("xxx").xxxx()這種寫法,其實是透過jQuery.fn.extend({xxx: function() {}})的方式進行方法繫結和擴充套件的,而$.xxx()這種方式的方法是透過jQuery.extend({xxx: function() {}})的方式進行方法繫結和擴充套件的;如下圖,$.ajax透過下圖繫結:
而$("xxxx").attr()則透過下面方式:
第二,console.log(jQuery()) 其實是個物件,
console.log(jQuery("#test")),如果有此元素存在,看起來像陣列,如下圖,其實也是物件,這種叫“類陣列”;可以百度去看下類陣列相關知識;
好,下面開始說下樓主的兩個問題,第一是extend的實現方法;第二是jquery為什麼能同時支援$.xxx()與$().xxx()這兩種寫法;
第一,extend的實現方法;由於原始碼較多,我在這兒就不直接展示出來了,有興趣可以去找到看看;其實簡單講,extend主要用於物件的合併,如下圖;
但是從原始碼可以看出,當引數只有一個物件的時候,就是直接將傳入物件合併到呼叫的物件上 (即jquery或jquery.fn);
所以,當呼叫jQuery.extend時,就會將傳入的物件裡面的方法合併寫入到jQuery物件上面,就可以對其進行擴充套件; 同理,使用jQuery.fn.extend時,就可以對jQuery.fn進行擴充套件;
第二,$.xxx()與$().xxx()兩種的區別;第一種$.xxx()其實是呼叫的jQuery物件上面的方法,也就是透過jQuery.extend進行擴充套件的方法;有人會說,jQuery是一個函式,但是函式在js也是物件,也可以向其新增屬性和方法;而第二種$().xxx()則是呼叫的jQuery.fn物件上面的方法,也就是透過jQuery.fn.extend進行擴充套件的方法;
第一種透過jQuery.extend進行擴充套件的屬性和方法是直接寫入jQuery物件,所以也就可以直接透過$.xxx()的方式呼叫,這個很容易理解;
第二種,透過jQuery.fn.extend進行擴充套件的方法和屬性為何能夠透過$().xxx()進行呼叫呢;這個就要從jQuery的整個架構來說;當執行$()時,訪問了下圖程式碼:可以看出,其實是例項化了一個jQuery.fn.init的物件;在這我們就不再討論jQuery.fn.init裡面具體幹了什麼,但可以透過原始碼可以看出,其最終執行了“return this”,也就是返回了jQuery.fn.init的例項物件;那如何透過$()可以訪問到jQuery.fn上面的屬性和方法呢?就是透過下圖這句程式碼:
它將jQuery.fn賦給了jQuery.fn.init.prototype,所以,jQuery.fn.init的例項物件也就可以直接訪問jQuery.fn上面的方法和屬性了;所以,當你透過$().xxx()時,其實訪問了jQuery.fn.xxx()方法;
其實,這個問題去看jquery原始碼就能很清楚的知道了,從樓主的問題說明裡面只是明白了jquery的方法擴充套件方式,但並沒有真正理解其主要架構方式;
我下面所說的都是基於2.0.3版本jquery原始碼進行說明,首先,描述中有幾個錯誤需要指正下:
第一,在jquery中,$("xxx").xxxx()這種寫法,其實是透過jQuery.fn.extend({xxx: function() {}})的方式進行方法繫結和擴充套件的,而$.xxx()這種方式的方法是透過jQuery.extend({xxx: function() {}})的方式進行方法繫結和擴充套件的;如下圖,$.ajax透過下圖繫結:
而$("xxxx").attr()則透過下面方式:
第二,console.log(jQuery()) 其實是個物件,
console.log(jQuery("#test")),如果有此元素存在,看起來像陣列,如下圖,其實也是物件,這種叫“類陣列”;可以百度去看下類陣列相關知識;
好,下面開始說下樓主的兩個問題,第一是extend的實現方法;第二是jquery為什麼能同時支援$.xxx()與$().xxx()這兩種寫法;
第一,extend的實現方法;由於原始碼較多,我在這兒就不直接展示出來了,有興趣可以去找到看看;其實簡單講,extend主要用於物件的合併,如下圖;
但是從原始碼可以看出,當引數只有一個物件的時候,就是直接將傳入物件合併到呼叫的物件上 (即jquery或jquery.fn);
所以,當呼叫jQuery.extend時,就會將傳入的物件裡面的方法合併寫入到jQuery物件上面,就可以對其進行擴充套件; 同理,使用jQuery.fn.extend時,就可以對jQuery.fn進行擴充套件;
第二,$.xxx()與$().xxx()兩種的區別;第一種$.xxx()其實是呼叫的jQuery物件上面的方法,也就是透過jQuery.extend進行擴充套件的方法;有人會說,jQuery是一個函式,但是函式在js也是物件,也可以向其新增屬性和方法;而第二種$().xxx()則是呼叫的jQuery.fn物件上面的方法,也就是透過jQuery.fn.extend進行擴充套件的方法;
第一種透過jQuery.extend進行擴充套件的屬性和方法是直接寫入jQuery物件,所以也就可以直接透過$.xxx()的方式呼叫,這個很容易理解;
第二種,透過jQuery.fn.extend進行擴充套件的方法和屬性為何能夠透過$().xxx()進行呼叫呢;這個就要從jQuery的整個架構來說;當執行$()時,訪問了下圖程式碼:可以看出,其實是例項化了一個jQuery.fn.init的物件;在這我們就不再討論jQuery.fn.init裡面具體幹了什麼,但可以透過原始碼可以看出,其最終執行了“return this”,也就是返回了jQuery.fn.init的例項物件;那如何透過$()可以訪問到jQuery.fn上面的屬性和方法呢?就是透過下圖這句程式碼:
它將jQuery.fn賦給了jQuery.fn.init.prototype,所以,jQuery.fn.init的例項物件也就可以直接訪問jQuery.fn上面的方法和屬性了;所以,當你透過$().xxx()時,其實訪問了jQuery.fn.xxx()方法;