JQuery源码解析(一)
jQuery使用戶能更方便地處理DOM、事件、實現動畫效果,并且方便地為網站提供AJAX交互。
2、jQuery的模塊依賴網:
jQuery一共13個模塊,模塊不是單一的,比如jQuery動畫,都會依賴異步隊列、動畫隊列、回調隊列與數據緩存模塊等。
jQuery抽出了所有可復用的特性,分離出單一模塊,通過組合的用法,不管在設計思路與實現手法上jQuery都是非常高明的。
五大塊:選擇器、DOM操作、事件、AJAX與動畫
那么為什么有13個模塊?因為jQuery的設計中最喜歡的做的一件事,就是抽出共同的特性使之“模塊化”,
當然也是更貼近S.O.L.I.D五大原則的“單一職責SRP”了,遵守單一職責的好處是可以讓我們很容易地來維護這個對象,
比如,當一個對象封裝了很多職責的時候,一旦一個職責需要修改,勢必會影響該對象的其它職責代碼。
通過解耦可以讓每個職責更加有彈性地變化。
我們來看看jQuery文檔針對業務層的Ajax的處理提供了一系列的門面接口:
?底層接口:
jQuery.ajax() jQuery.ajaxSetup()?快捷方法:
jQuery.get() jQuery.getJSON() jQuery.getScript() jQuery.post()?jQuery接口的設計原理
業務邏輯是復雜多變的,jQuery的高層API數量非常多,而且也非常的細致,這樣做可以更友好的便于開發者的操作,
不需要必須在一個接口上重載太多的動作。我們在深入內部看看Ajax的高層方法其實都是統一調用了一個靜態的jQuery.ajax方法,
代碼見右側代碼編輯器(27-43行)。
在jQuery.ajax的內部實現是非常復雜的,首先ajax要考慮異步的處理與回調的統一性,
所以就引入了異步隊列模塊(Deferred)與回調模塊(Callbacks), 所以要把這些模塊方法在ajax方法內部再次封裝成、
構建出一個新的jQXHR對象,針對參數的默認處理,數據傳輸的格式化等等。
?
二:立即調用表達式
任何庫與框架設計的第一個要點就是解決命名空間與變量污染的問題。
jQuery就是利用了JavaScript函數作用域的特性,采用立即調用表達式包裹了自身的方法來解決這個問題。
jQuery的立即調用函數表達式的寫法有三種:
寫法1:
(function(window, factory) {factory(window) }(this, function() {return function() {//jQuery的調用} }))?可以看出上面的代碼中嵌套了2個函數,而且把一個函數作為參數傳遞到另一個函數中并且執行,這種方法有點復雜,我們簡化一下寫法:
寫法2:
var factory = function(){return function(){//執行方法} } var jQuery = factory();?上面的代碼效果和方法1是等同的,但是這個factory有點變成了簡單的工廠方法模式,需要自己調用,不像是一個單例的jQuery類,所以我們需要改成“自執行”,而不是另外調用。
寫法3:
(function(window, undefined) {var jQuery = function() {}// ...window.jQuery = window.$ = jQuery; })(window);?從上面的代碼可看出,自動初始化這個函數,讓其只構建一次。詳細說一下這種寫法的優勢:
??1、window和undefined都是為了減少變量查找所經過的scope作用域。當window通過傳遞給閉包內部之后,
在閉包內部使用它的時候,可以把它當成一個局部變量,顯然比原先在window scope下查找的時候要快一些。
??2、undefined也是同樣的道理,其實這個undefined并不是JavaScript數據類型的undefined,而是一個普普通通的變量名。
只是因為沒給它傳遞值,它的值就是undefined,undefined并不是JavaScript的保留字。
?
為什么要傳遞undefined?
Javascript 中的 undefined 并不是作為關鍵字,因此可以允許用戶對其賦值。?var undefined = '孫麗媛' ;(function(window) { alert(undefined);//IE8 '孫麗媛' })(window)
IE8存在這個問題,當然,大部分瀏覽器都是不能被修改的
如果函數調用不傳遞,參數默認就是undefined
;(function(window,undefined) {//undefined })(window)?
jQuery為什么要創建這樣的一個外層包裹,其原理又是如何?
這里要區分2個概念一個是匿名函數,一個是自執行。顧名思義,匿名函數,就是沒有函數名的函數,也就是不存在外部引用。但是是否像下面代碼實現呢:
function(){ //代碼邏輯 }?上面這種寫法是錯了,聲明了它但是又不給名字又沒有使用,所以在語法上錯誤的,那么怎么去執行一個匿名的函數呢?
要調用一個函數,我們必須要有方法定位它、引用它。所以,我們要取一個名字:
?jQuery使用()將匿名函數括起來,然后后面再加一對小括號(包含參數列表),那么這小括號能把我們的表達式組合分塊,
并且每一塊(也就是每一對小括號),都有一個返回值。這個返回值實際上也就是小括號中表達式的返回值。
所以,當我們用一對小括號把匿名函數括起來的時候,實際上小括號返回的,就是一個匿名函數的Function對象。
因此,小括號對加上匿名函數就如同有名字的函數般被我們取得它的引用位置了。
所以如果在這個引用變量后面再加上參數列表,就會實現普通函數的調用形式。
最后,我們回到寫法1看看jQuery利用寫法3的寫法,然后把整個函數作為參數傳遞給另外一個函數,
主要是為了判斷jQuery在不同平臺的下的加載邏輯,主流的庫一般都有對 AMD 和 CommonJS 的支持代碼,看看jQuery的代碼:
if (typeof module === "object" && typeof module.exports === "object") {module.exports = global.document ?factory(global, true) :function(w) {if (!w.document) {throw new Error("jQuery requires a window with a document");}return factory(w);}; } else {factory(global); }?總結:全局變量是魔鬼,?匿名函數可以有效的保證在頁面上寫入JavaScript,而不會造成全局變量的污染,
通過小括號,讓其加載的時候立即初始化,這樣就形成了一個單例模式的效果從而只會執行一次。
?
轉載于:https://www.cnblogs.com/sunliyuan/p/6026064.html
總結
以上是生活随笔為你收集整理的JQuery源码解析(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring-cloud 学习三 服务提
- 下一篇: JAVA学习笔记-“Hello Worl