您好,登錄后才能下訂單哦!
最近花了一些時間看了一下jQuery的源碼,以下部分是我對源碼的核心部分進行的提取。這樣能更清晰的看清jQuery本身的結構,接下來對這段核心的代碼進行詳細的分析。只限于對目前對jQuery的理解層次。
1.首先jQuery同樣被包裹在一個匿名塊里面,接著對這個匿名塊進行了調用,
并且傳遞的參數為window,可能還包括undefined,在這部分暫不做分析。
之所以傳遞window進入到匿名塊中,是為了接下來核心代碼形成的閉包,
減少了對作用域鏈層次的查詢。這樣在jQuery的內部中訪問window會更快些。
2.接下來定義一個匿名函數并對其進行調用,這個匿名函數有一個返回值就是jQuery對象
隨后將返回值(jQuery對象)賦值給變量jQuery(代碼的3行和23行)。
注意:這個函數只會執行一次,這是jQuery設計巧妙地方之一。
最后在window上定義兩個屬性$和jQuery,其值也就是剛剛通過匿名函數的返回值jQuery。
這也是一般庫的做法,這樣$和jQuery就會存在于全局上下文的變量對象中。在程序的任何地方都可以訪問到。
3.代碼中(5-22行)才是真正的jQuery對象的核心。在jQuery匿名塊的內部定義了一個構造函數名字也叫jQuery。
所有的jQuery對象都是通過這個構造方法構造的。這個方法非常簡單,接收一個參數也就是選擇器的名字,new一個
jQuery.fn.init對象并且返回。這樣我們就會得到一個符合當前選擇器的jQuery對象。
4.代碼中(9-18行)是jQuery的原型,一切的巧妙設計都在這里。
首先拋去jQuery.fn不看,那這很簡單就是jQuery構造函數的原型。constructor有指回了jQuery的構造函數。
原型里面有一個方法init,兩個屬性length、splice。那這幾個東西到底有什么用呢?
首先init方法其實就是根據我們提供的選擇器進行DOM查詢最終并返回的過程,這里暫不細講。
當一個ECMA對象擁有length、splice兩個屬性時,這個對象就會成為一個數組,因為ECMA中數組也是對象。
好,在處理完jQuery構造函數的原型后,又在jQuery構造函數(對象)上定義了一個屬性fn也就是jQuery.fn。
最后將jQuery構造函數的原型的引用賦值給了jQuery.fn,這其實是對原型的一次緩存,以免以后頻繁使用原型。
方便實現插件機制。
5.進行到現在你可能會發現一個問題,為什么每次調用jQuery無論選擇器是什么,都會得到一些相同的方法呢?
也就是說當使用$('#demo')時,首先給jQuery的構造函數傳遞'#demo',然后new一個jQuery.fn.init也就是
jQuery構造函數原型里面的方法,最后得到一個DOM對象的引用,但這時這個對象是不具備length、splice屬性的
也就是說不具備其它jQuery方法的。--當然這里我沒有寫。到底是什么原因改變了這一切使其具備了呢?
代碼(20行)jQuery構造函數的原型的引用又賦值給了init的原型,這樣通過init函數new出來的對象也就具備了
jQuery構造函數的原型上的所有屬性。這真是一種巧妙的設計。
總結:
好了現在總結一下整個jQuery實現的流程,比如當我們使用$('#demo')時,會進入jQuery的構造方法,但是并沒用
通過這個方法去new一個實例。而是通過new一個jQuery構造函數原型里面的init構造方法的實例,這個方法做了一件事
就是查找DOM元素并返回。而通過將jQuery構造函數的原型的引用賦值給這個init構造函數的原型。是這個剛剛構造出來
的這個實例擁有所有的jQuery屬性、方法。那么,每次根據選擇器調用jQuery的時候,都只是查找并返回一個實例而已,
而其屬性和方法早已通過原型機制獲得了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。