宏觀解析jQuery框架源碼
作者:金廣國(guó)
宏觀而言,jQuery框架可分為3個(gè)步驟——1.定義jQuery變量;.擴(kuò)充jQuery變量及jQuery.fn變量(利用jQuery及jQuery.fn命名空間進(jìn)行方法的填充);3.將jQuery置于全局
對(duì)于jQuery只停留在應(yīng)用是可悲的,在做項(xiàng)目的過(guò)程,jquery源碼一度成為了自己開(kāi)發(fā)的瓶頸,利用了近一天的時(shí)間對(duì)其宏觀上進(jìn)行了徹底的分析,收獲頗豐,分享于此——
在此說(shuō)明,所研究的jQuery框架版本為1.7.2。
宏觀而言,jQuery框架可分為3個(gè)步驟——
1.定義jQuery變量 2.擴(kuò)充jQuery變量及jQuery.fn變量(利用jQuery及jQuery.fn命名空間進(jìn)行方法的填充) 3.將jQuery置于全局 |
其細(xì)節(jié)如下——
- /**
- * 1.定義jQuery變量
- * var jQuery = (function () {
- *
- * //定義一個(gè)局部變量jQuery
- * var jQuery = function(selector, context) {
- * //這是所有jQuery選擇器的開(kāi)始
- * return new jQuery.fn.init(selector, context, rootjQuery);
- * },
- *
- * //接著定義其他變量,最主要的是對(duì)jQuery函數(shù)原型的改造
- * //兩者皆為指針,并指向同一起始位置,但后續(xù)對(duì)兩個(gè)對(duì)象的擴(kuò)充,使得兩者能夠指向的位置域有所不同
- * jQuery.fn = jQuery.prototype = {
- * constructor: jQuery,
- * init: function(){...},//定義了所有jQuery選擇器的開(kāi)始
- * //還定義了其他的基礎(chǔ)方法,如
- * size: function(){...},
- * toArray: function(){...},
- * get: function(){...},
- * ......
- * port: [].sort,
- * splice: [].splice
- * };
- *
- * //對(duì)上面定義的init函數(shù)重置原型
- * jQuery.fn.init.prototype = jQuery.fn;
- *
- * //實(shí)現(xiàn)了jQuery原型的擴(kuò)充
- * jQuery.extend = jQuery.fn.extend = function() {
- * ......
- * }
- *
- * //定義完jQuery命名空間下的extend方法,就可以直接擴(kuò)充jQuery原型了
- * jQuery.extend({
- * noConflict: function(deep){...},
- * //一系列方法...
- * })
- *
- * //鑒別構(gòu)造器語(yǔ)句...
- * //鑒別瀏覽器語(yǔ)句...
- * //其他...
- *
- * //要返回這個(gè)局部變量jQuery對(duì)象,賦值給外圍的jQuery變量
- * return jQuery;
- *
- * )();
- *
- * 2.擴(kuò)充jQuery變量及jQuery.fn變量(利用jQuery及jQuery.fn命名空間進(jìn)行方法的填充)
- * 核心的兩個(gè)方法——
- * jQuery.extend({...})
- * jQuery.fn.extend({...})
- *
- * 3.將jQuery置于全局
- * 在代碼的***——
- * window.jQuery = window.$ = jQuery;
- *
- */
選取3個(gè)例子進(jìn)行深入研究——
- (function ($) {
- /**
- * 測(cè)試-jquery選擇器方法(初始化)、測(cè)試-append方法,流程解析如下——
- * 1>$('#test', 'body')調(diào)用jQuery函數(shù)(var jQuery = function(selector, context) {return new jQuery.fn.init(selector, context, rootjQuery);})
- * 先對(duì)選擇器selector(即#test),進(jìn)行初始化,即(jQuery.fn.init('#test', 'body', [#document]))
- * 發(fā)現(xiàn)有context(即body),那么要對(duì)body進(jìn)行初始化,再調(diào)用$(context).find(selector)方法(即$('body').find('body'))
- * 2>對(duì)于append方法:會(huì)調(diào)用jQuery.fn.domManip方法(這個(gè)方法會(huì)調(diào)用jQuery.buildFragment方法),最終會(huì)調(diào)用selector的dom元素的appendChild方法進(jìn)行dom操作
- */
- $('#test', 'body').append('<div class="c2">implant content<div>');
- /**
- * 測(cè)試-擴(kuò)展jQuery對(duì)象本身,即,用來(lái)在jQuery命名空間上增加新函數(shù)
- * 看了源碼就會(huì)發(fā)現(xiàn):
- * 它循環(huán)了傳入的對(duì)象參數(shù)里面的key-value值,并對(duì)jQuery這個(gè)函數(shù)對(duì)象做了擴(kuò)展,其key值正是傳參的key值(min和max)
- */
- $.extend({
- min: function(a, b) { return a < b ? a : b; },
- max: function(a, b) { return a > b ? a : b; }
- });
- $.min(2,3); //2
- /**
- * 測(cè)試-擴(kuò)展 jQuery 元素集來(lái)提供新的方法(通常用來(lái)制作插件)。
- * 看了源碼就會(huì)發(fā)現(xiàn):
- * 它與jQuery.extend的調(diào)用方法是同一個(gè)方法,只不過(guò)它對(duì)jQuery.fn這個(gè)命名空間做了功能擴(kuò)展
- */
- $.fn.extend({
- check: function() {
- return this.each(function() {
- this.checked = true;
- });
- },
- uncheck: function() {
- return this.each(function() {
- this.checked = false;
- });
- }
- });
- /**
- * 搜索jQuery變量,只要在這個(gè)代碼段之前引入jQuery.js框架即可,在這個(gè)框架中,會(huì)把jQuery變量放置到window對(duì)象中
- * 源碼如下:
- * // Expose jQuery to the global object
- * window.jQuery = window.$ = jQuery; //這句放在了框架中的***一句,
- * //這句之前,在框架中對(duì)jQuery這個(gè)局部對(duì)象變量(命名空間),做了方法及屬性的填充
- */
- })(jQuery);
- /**
- * 需要的前提知識(shí)——
- * 1.JS執(zhí)行順序
- * 1>預(yù)解析
- * 2>執(zhí)行
- * 2.函數(shù)作用域
- * 1>this(深入理解函數(shù)調(diào)用模式)
- * 2>變量檢索(深入理解變量對(duì)象VO)
- * 3>模塊模式(深入理解閉包)
- * 3.函數(shù)原型繼承
- */
- /**
- * 從源碼的架構(gòu)可以學(xué)到
- * 1.對(duì)于重復(fù)利用的變量,提前重新賦值,置為局部變量,這樣就減少了變量查找的過(guò)程,提高了性能,如:
- * var document = window.document,
- * navigator = window.navigator,
- * location = window.location;
- * 2.單變量置頂集中聲明
- * 在每一個(gè)函數(shù)執(zhí)行域中,把所有該函數(shù)所需要的變量在這個(gè)函數(shù)域的最頂端進(jìn)行聲明,利于變量管理,提高性能,利于維護(hù)
- * 3.絕大部分函數(shù)定義用的是函數(shù)表達(dá)式的方式,而非函數(shù)聲明的方式,這種方式利于代碼維護(hù),值得借鑒
- * 4.代碼組織方式
- * 1>整體而言,深度利用命名空間的方式管理自己的代碼,極大的提高的代碼的維護(hù)性,值得借鑒
- * 2>利用模塊模式,充分劃分哪些變量及函數(shù)是私有的。利用命名空間的方式,充分劃分哪些變量及函數(shù)是公有的。
- * 3>功能模塊化:并沒(méi)有一次性將所需要的功能函數(shù)擴(kuò)充于jQuery或jQuery.fn命名空間中,而是充分利用模塊化思想進(jìn)行劃分。
- * 4>源碼中的每一個(gè)函數(shù)都是以key-value(這里的value是函數(shù))的形式置于某個(gè)命名空間中,而不是簡(jiǎn)單的功能function的平鋪。
- * 增加了代碼的維護(hù)性,值得借鑒。
- */
- /**
- * 研究jquery框架的作用:
- * 1.在做基于jquery框架的項(xiàng)目時(shí),可依據(jù)所需性能合理使用里面的方法,
- * 例如,能完成同樣一項(xiàng)功能的兩個(gè)方法,我們當(dāng)然要選擇性能高的一個(gè)方法
- * 2.理解了整體架構(gòu),對(duì)于細(xì)節(jié)方法的具體實(shí)現(xiàn),可根據(jù)應(yīng)用具體分析
- * 3.對(duì)于以后研究基于jquery的框架(如jquery.validate.js或jquery.ptTimeSelect.js)就不再成為難點(diǎn)
- * 4.記住jquery框架的編碼風(fēng)格,利于對(duì)比其他優(yōu)秀框架,吸取其精華
- */
原文鏈接:http://www.cnblogs.com/jinguangguo/archive/2012/10/31/2748766.html
責(zé)任編輯:張偉
來(lái)源:
博客園