天天看點

jquery核心功能分析(帶圖解)

作者:zccst

整體架構

jQuery架構的核心就是從HTML文檔中比對元素并對其執行操作、

例如:

$().find().css()

$().hide().html('....').hide().

從上面的寫法上至少可以發現2個問題

1. jQuery對象的建構方式

2 .jQuery方法的調用方式

分析一:jQuery的無new建構

JavaScript是函數式語言,函數可以實作類,類就是面向對象程式設計中最基本的概念

通過new aQuery(),雖然傳回的是一個執行個體,但是也能看出很明顯的問題,死循環了!

那麼如何傳回一個正确的執行個體?

在javascript中執行個體this隻跟原型有關系

那麼可以把jQuery類當作一個工廠方法來建立執行個體,把這個方法放到jQuery.prototye原型中

當執行aQuery() 傳回的執行個體:

[img]http://dl2.iteye.com/upload/attachment/0101/1759/05367159-bf84-3851-b41b-8698308ba48e.png[/img]

很明顯aQuery()傳回的是aQuery類的執行個體,那麼在init中的this其實也是指向的aQuery類的執行個體

問題來了init的this指向的是aQuery類,如果把init函數也當作一個構造器,那麼内部的this要如何處理?

這樣的情況下就出錯了,因為this隻是指向aQuery類的,是以需要設計出獨立的作用域才行

jQuery架構分隔作用域的處理

jQuery = function( selector, context ) {

// The jQuery object is actually just the init constructor 'enhanced'

return new jQuery.fn.init( selector, context, rootjQuery );

},

很明顯通過執行個體init函數,每次都建構新的init執行個體對象,來分隔this,避免互動混淆

那麼既然都不是同一個對象那麼肯定又出現一個新的問題

例如:

抛出錯誤,無法找到這個方法,是以很明顯new的init跟jquery類的this分離了

怎麼通路jQuery類原型上的屬性與方法?

做到既能隔離作用域還能使用jQuery原型對象的作用域呢,還能在傳回執行個體中通路jQuery的原型對象?

實作的關鍵點

// Give the init function the jQuery prototype for later instantiation

jQuery.fn.init.prototype = jQuery.fn;

通過原型傳遞解決問題,把jQuery的原型傳遞給jQuery.prototype.init.prototype

換句話說jQuery的原型對象覆寫了init構造器的原型對象

因為是引用傳遞是以不需要擔心這個循環引用的性能問題

百度借網友的一張圖,友善直接了解:

[img]http://dl2.iteye.com/upload/attachment/0101/1755/bf86f015-f2b0-33ce-b8c4-bd856dcf8bf1.jpg[/img]

fn解釋下,其實這個fn沒有什麼特殊意思,隻是jQuery.prototype的引用

分析二:鍊式調用

DOM鍊式調用的處理:

1.節約JS代碼.

2.所傳回的都是同一個對象,可以提高代碼的效率

通過簡單擴充原型方法并通過return this的形式來實作跨浏覽器的鍊式調用。

利用JS下的簡單工廠模式,來将所有對于同一個DOM對象的操作指定同一個執行個體。

這個原理就超簡單了

aQuery().init().name()

分解

a = aQuery();

a.init()

a.name()

把代碼分解一下,很明顯實作鍊式的基本條件就是執行個體this的存在,并且是同一個

是以我們在需要鍊式的方法通路this就可以了,因為傳回目前執行個體的this,進而又可以通路自己的原型了

aQuery.init().name()

優點:節省代碼量,提高代碼的效率,代碼看起來更優雅

最糟糕的是所有對象的方法傳回的都是對象本身,也就是說沒有傳回值,這不一定在任何環境下都适合。

Javascript是無阻塞語言,是以他不是沒阻塞,而是不能阻塞,是以他需要通過事件來驅動,異步來完成一些本需要阻塞程序的操作,這樣處理隻是同步鍊式,異步鍊式jquery從1.5開始就引入了Promise,jQuery.Deferred後期在讨論。

如果您覺得本文的内容對您的學習有所幫助,您可以微信:

[img]http://dl2.iteye.com/upload/attachment/0109/0668/fb266dfa-95ca-3d09-b41e-5f04a19ba9a1.png[/img]

繼續閱讀