jQuery 源碼分析筆記(2) 變數列表

來源:互聯網
上載者:User

_jQuery = window.jQuery;
_$ = window.$;
這兩個變數是jQuery唯一使用的兩個全域變數。在jQuery.noConflict()函數中,會把這兩個變數恢複回去。
對於瀏覽器檢測,jQuery使用的是檢查UserAgent,而沒有使用特性檢測。
rwebkit = /(webkit)[ \/]([\w.]+)/,
ropera = /(opear)(?:.*version)?[ \/](\w+)/,
rmsie = /(msie) ([\w.]+)/,
rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
初始化函數init
jQuery對JS對象的處理比較繞,而最終目的就是把jQuery選取器得到的結果變成和數組差不多的一個對象。有length,first,last等。因為$("...")就是從DOM樹從選擇一些節點出來。但是,$還有很多其他功能,比如常用的$(function() { ... })用來頁面載入後初始化執行,$("<..>...</...>")來直接得到一個節點,用來append到DOM樹中。
接下來從93行開始就是很長的一段init函數。Init: function(selector, context, rootjQuery)
步驟:
1、Selector是非法參數:Null 字元,null和undefined則直接返回this。即有預設屬性的jQuery對象。
2、Selector是DOMElement。即用原生的JS,比如getElementById等得到的元素。那麼,相當於把原生的DOM對象用$封裝一次。把這個元素放到內部數組的第一個位置,並把length設定為1。然後返回。
3、特殊最佳化處理$("body")。即document.body元素。
4、Selector是以<開頭,以>結尾的字串。那麼假定是想用字串建立一個DOM元素。比如$("<a href='http://www.cnblogs.com">部落格園</a>")。為了安全起見,這裡使用了一個Regex來檢查,到底是<...>...</...>形式還是#id的形式。
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/。在quickExpr.exec(selector)後,如果是HTML字串,那麼會得到[match, match, undefined],而#id形式會得到[#id, undefined, id]的結果。這樣就把字串區別開了。
對於HTML字串,如果只有一個tag,那麼直接調用createElement。否則調用一個createFragment輔助函數,這個函數使用createDocumentFragment,然後把所有tag都插進去。
createFragment實現在5892行,這裡有一個值得注意的地方就是jQuery對於HTML片段做了緩衝處理。而且對於不同的瀏覽器和元素有不同的處理,作者寫了大段的注釋說明。歸納起來就是(1)只緩衝小於0.5KB的小片段。(2)selected狀態不緩衝。(3)IE6的<object>和<embed>元素不緩衝。(4)WebKit不緩衝元素的checked屬性。以上這些不緩衝的原因是jQuery使用複製(Clone)節點的方式進行緩衝,而2-4提到的情況在Clone時會丟失。jQuery使用了正則,或者jQuery.support輔助函數來進行是否緩衝的策略判斷。這裡先略過。jQuery.support牽扯很多瀏覽器相關問題。
5、如果在4中檢查到是#id,則直接調用document.getElementById
6、如果selector是function,則把這個函數當作是document.ready的事件處理函數
7、剩餘的各種情況,比如傳入了context等。統一調用一個find(selector)來處理。這個函數以後再議。(5109行,jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; 表明,其他複雜的selector運算式都扔給Sizzle項目了)
jQuery基本成員
jQuery被設計成一個行為和數組很像的對象。所以需要一些轉換方法和基本屬性。
1、jquery:版本號碼。最簡單的得到版本號碼的方式:$().jquery
2、length和size():長度。
3、toArray():轉換成JS數組
4、get(num):返回第N個元素。如果傳入null,則直接返回toArray()的結果。這裡返回的就是DOMElement了。
5、pushStack():參見http://api.jquery.com/pushStack/ 。內部new了一個新的jQuery對象,然後把elems和selector得到的結果合并進去,然後返回這個新的jQuery對象。這裡有個prevObject屬性的設定,往下看end()函數。
6、each(callback, args):遍曆數組內的元素。內部調用了$.each Utiltiy。
7、ready(fn):其實和$(function() { })是等價的。
8、eq(i):i允許正負數字,而且返回的仍然是jQuery對象,只不過只有一個元素了。其實只是slice的封裝。
9、first()和last():其實就是eq(0)和eq(-1),很簡單的一個封裝。
10、slice():根據參數獲得數組一部分的引用。內部使用pushStack實現的。所以返回的也是一個新的jQuery對象。
11、map(callback):對每個元素依次調用callback。把原來的元素A的數組映射為元素B的數組。callback就是元素A->元素B的映射函數。函數式編程(FP)裡很基礎的一個概念。
12、end(): 參見http://api.jquery.com/end 。這個是返回選取器的上一個狀態。返回的是jQuery.prevObject屬性。這個屬性是在pushStack函數裡面設定的,它在返回新的jQuery對象之前,把這個新對象的prevObject設定為this。這樣多次pushStack之後就變成了一個鏈表(chain)。而end()就是沿著鏈表往前走一個節點。經過了selector之後,根的prevObject是document。比如$("body div").prevObject就是Document。
extend函數
在jQuery基本成員之後,所有其他成員都是用extend加上去的。聲明:
jQuery.extend = jQuery.fn.extend = function() { }
把target後面的所有object參數的屬性全部賦值到target上,如果第一個參數是boolean值,則用來指定是否深拷貝。然後返回修改過的target(不是新對象,extend函數直接修改原對象)。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.