宏觀解析jQuery框架源碼


  對於jQuery只停留在應用是可悲的,在做項目的過程,jquery源碼一度成為了自己開發的瓶頸,利用了近一天的時間對其宏觀上進行了徹底的分析,收獲頗豐,分享於此——

  在此說明,所研究的jquery框架版本為1.7.2。

  宏觀而言,jQuery框架可分為3個步驟——

  1.定義jQuery變量
  2.擴充jQuery變量及jQuery.fn變量(利用jQuery及jQuery.fn命名空間進行方法的填充)
  3.將jQuery置於全局

  其細節如下——

 1 /**
 2  * 1.定義jQuery變量
 3  *  var jQuery = (function () {
 4  *     
 5  *        //定義一個局部變量jQuery
 6  *        var jQuery = function(selector, context) {
 7  *            //這是所有jQuery選擇器的開始
 8  *            return new jQuery.fn.init(selector, context, rootjQuery);
 9  *        },
10  *        
11  *        //接着定義其他變量,最主要的是對jQuery函數原型的改造
12  *         //兩者皆為指針,並指向同一起始位置,但后續對兩個對象的擴充,使得兩者能夠指向的位置域有所不同
13  *        jQuery.fn = jQuery.prototype = {
14  *            constructor: jQuery,
15  *            init: function(){...},//定義了所有jQuery選擇器的開始
16  *            //還定義了其他的基礎方法,如
17  *            size: function(){...},
18  *            toArray: function(){...},
19  *            get: function(){...},
20  *            ......
21  *            port: [].sort,
22  *            splice: [].splice
23  *        };
24  *        
25  *        //對上面定義的init函數重置原型
26  *        jQuery.fn.init.prototype = jQuery.fn;
27  *        
28  *        //實現了jQuery原型的擴充
29  *        jQuery.extend = jQuery.fn.extend = function() {
30  *            ......
31  *        }
32  *        
33  *        //定義完jQuery命名空間下的extend方法,就可以直接擴充jQuery原型了
34  *        jQuery.extend({
35  *            noConflict: function(deep){...},
36  *            //一系列方法...
37  *        })
38  *        
39  *        //鑒別構造器語句...
40  *        //鑒別瀏覽器語句...
41  *        //其他...
42  *        
43  *        //要返回這個局部變量jQuery對象,賦值給外圍的jQuery變量
44  *        return jQuery;
45  *    
46  *    )();
47  * 
48  * 2.擴充jQuery變量及jQuery.fn變量(利用jQuery及jQuery.fn命名空間進行方法的填充)
49  *     核心的兩個方法——
50  *     jQuery.extend({...})
51  *     jQuery.fn.extend({...})
52  * 
53  * 3.將jQuery置於全局
54  *     在代碼的最后——
55  *     window.jQuery = window.$ = jQuery;
56  * 
57  */

  選取3個例子進行深入研究——

 1 (function ($) {
 2     
 3     /**
 4      * 測試-jquery選擇器方法(初始化)、測試-append方法,流程解析如下——
 5      * 1>$('#test', 'body')調用jQuery函數(var jQuery = function(selector, context) {return new jQuery.fn.init(selector, context, rootjQuery);})
 6      *     先對選擇器selector(即#test),進行初始化,即(jQuery.fn.init('#test', 'body', [#document]))
 7      *     發現有context(即body),那么要對body進行初始化,再調用$(context).find(selector)方法(即$('body').find('body'))
 8      * 2>對於append方法:會調用jQuery.fn.domManip方法(這個方法會調用jQuery.buildFragment方法),最終會調用selector的dom元素的appendChild方法進行dom操作
 9      */
10     $('#test', 'body').append('<div class="c2">implant content<div>');    
11     
12     /**
13      * 測試-擴展jQuery對象本身,即,用來在jQuery命名空間上增加新函數
14      * 看了源碼就會發現:
15      *     它循環了傳入的對象參數里面的key-value值,並對jQuery這個函數對象做了擴展,其key值正是傳參的key值(min和max)
16      */
17     $.extend({
18         min: function(a, b) { return a < b ? a : b; },
19         max: function(a, b) { return a > b ? a : b; }
20     });
21     $.min(2,3); //2
22     
23     /**
24      * 測試-擴展 jQuery 元素集來提供新的方法(通常用來制作插件)。
25      * 看了源碼就會發現:
26      *     它與jQuery.extend的調用方法是同一個方法,只不過它對jQuery.fn這個命名空間做了功能擴展
27      */
28     $.fn.extend({
29         check: function() {
30             return this.each(function() { 
31                 this.checked = true; 
32             });
33         },
34         uncheck: function() {
35             return this.each(function() { 
36                 this.checked = false; 
37             });
38         }
39     });
40     
41 /**
42  * 搜索jQuery變量,只要在這個代碼段之前引入jQuery.js框架即可,在這個框架中,會把jQuery變量放置到window對象中
43  * 源碼如下:
44  *         // Expose jQuery to the global object
45  *         window.jQuery = window.$ = jQuery;  //這句放在了框架中的最后一句,
46  *                                             //這句之前,在框架中對jQuery這個局部對象變量(命名空間),做了方法及屬性的填充
47  */
48 })(jQuery);
/**
 * 需要的前提知識——
 * 1.JS執行順序
 *         1>預解析
 *         2>執行
 * 2.函數作用域
 *         1>this(深入理解函數調用模式)
 *         2>變量檢索(深入理解變量對象VO)
 *         3>模塊模式(深入理解閉包)
 * 3.函數原型繼承
 */
/**
 * 從源碼的架構可以學到
 * 1.對於重復利用的變量,提前重新賦值,置為局部變量,這樣就減少了變量查找的過程,提高了性能,如:
 *     var document = window.document, 
 *       navigator = window.navigator, 
 *       location = window.location;
 * 2.單變量置頂集中聲明
 *     在每一個函數執行域中,把所有該函數所需要的變量在這個函數域的最頂端進行聲明,利於變量管理,提高性能,利於維護
 * 3.絕大部分函數定義用的是函數表達式的方式,而非函數聲明的方式,這種方式利於代碼維護,值得借鑒
 * 4.代碼組織方式
 *     1>整體而言,深度利用命名空間的方式管理自己的代碼,極大的提高的代碼的維護性,值得借鑒
 *     2>利用模塊模式,充分划分哪些變量及函數是私有的。利用命名空間的方式,充分划分哪些變量及函數是公有的。
 *     3>功能模塊化:並沒有一次性將所需要的功能函數擴充於jQuery或jQuery.fn命名空間中,而是充分利用模塊化思想進行划分。
 *     4>源碼中的每一個函數都是以key-value(這里的value是函數)的形式置於某個命名空間中,而不是簡單的功能function的平鋪。
 *         增加了代碼的維護性,值得借鑒。
 */
/**
 * 研究jquery框架的作用:
 * 1.在做基於jquery框架的項目時,可依據所需性能合理使用里面的方法,
 *     例如,能完成同樣一項功能的兩個方法,我們當然要選擇性能高的一個方法
 * 2.理解了整體架構,對於細節方法的具體實現,可根據應用具體分析
 * 3.對於以后研究基於jquery的框架(如jquery.validate.js或jquery.ptTimeSelect.js)就不再成為難點
 * 4.記住jquery框架的編碼風格,利於對比其他優秀框架,吸取其精華
 */


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM