摘要:節(jié)點(diǎn)修改對(duì)象的屬性,這就相當(dāng)于把對(duì)象轉(zhuǎn)成了一個(gè)類(lèi)數(shù)組,最后返回,可用于鏈?zhǔn)秸{(diào)用。如果傳入的是單標(biāo)簽,且第二個(gè)參數(shù)是一個(gè)純對(duì)象例如則把后面對(duì)象的屬性一一添加到創(chuàng)建的這個(gè)節(jié)點(diǎn)的屬性上。
我們先看看jQuery的原型中初始化了哪些屬性和方法:
jQuery.fn = jQuery.prototype = { jquery: core_version, //jquery版本號(hào) constructor: jQuery, //構(gòu)造器指向 init: //jquery的入口函數(shù),主要用來(lái)實(shí)現(xiàn)選擇器和DOM節(jié)點(diǎn)的創(chuàng)建 selector: //將選擇器進(jìn)行存儲(chǔ) length: //當(dāng)前選擇器存儲(chǔ)的DOM節(jié)點(diǎn)的個(gè)數(shù) toArray: //通過(guò)方法借調(diào)的方式,把一個(gè)類(lèi)數(shù)組對(duì)象轉(zhuǎn)換為一個(gè)數(shù)組 //類(lèi)數(shù)組對(duì)象就是指有數(shù)字作為屬性,且有l(wèi)ength屬性,jQuery是一個(gè)類(lèi)數(shù)組對(duì)象,arguments也是。 get: //獲取jQuery對(duì)象中的某一個(gè)DOM節(jié)點(diǎn),返回的是一個(gè)DOM節(jié)點(diǎn), pushStack: //將一個(gè)DOM元素集合加入到j(luò)Query對(duì)象的prevObject中。 //this.prevObject=this,讓當(dāng)前DOM集合存儲(chǔ)到prevObject屬性中,方便end()調(diào)用是回溯。 each: //對(duì)數(shù)組進(jìn)行遍歷 ready: //當(dāng)DOM樹(shù)加載完畢后,回調(diào)該函數(shù) slice: //類(lèi)似于toArray方法,只是該方法會(huì)進(jìn)行一次pushStack操作 first: //返回第一個(gè)元素的jQuery對(duì)象 last: //返回最后一個(gè)元素的jQuery對(duì)象 eq: //傳入一個(gè)數(shù)字num,獲取第num個(gè)元素的jQuery對(duì)象 map: //map將一個(gè)數(shù)組中的元素轉(zhuǎn)換到另一個(gè)數(shù)組中,可以傳入一個(gè)回調(diào)函數(shù),作用與each類(lèi)似,只是map會(huì)返回一個(gè)新的數(shù)組,而each不會(huì) end: //返回調(diào)用parent()、find()、filter()等方法之前的jQuery對(duì)象,就是回溯到上一個(gè)DOM合集 push: core_push, //存儲(chǔ)了數(shù)組的push方法 sort: [].sort, //存儲(chǔ)了數(shù)組的sort方法 splice: [].splice //存儲(chǔ)了數(shù)組的splice方法 }
上面是對(duì)jQuery初始化的一些方法和屬性的介紹,前面初始化jQuery對(duì)象時(shí),我們可以看到j(luò)Query對(duì)象其實(shí)是一個(gè)實(shí)例化的jQuery.fn.init,所以這里主要看下init是如何實(shí)現(xiàn),其余的方法在具體用到的時(shí)候再看。
首先可以觀察到init方法傳入了三個(gè)參數(shù):
init: function( selector, context, rootjQuery ) {...}
selector(選擇器)
context(上下文環(huán)境)
rootJQuery( $(document) )
rootjQuery = jQuery(document);//參見(jiàn)866行
init對(duì)傳入的選擇器進(jìn)行了以下的區(qū)分:
空 : 包括 "" false undefined null
if ( !selector ) {return this;}
string:這個(gè)部分判斷有點(diǎn)復(fù)雜,會(huì)在后面詳細(xì)的介紹。
if ( typeof selector === "string" )...
DOM節(jié)點(diǎn):修改jQuery對(duì)象的屬性 0:selector,length:1 ;這就相當(dāng)于把jQuery對(duì)象轉(zhuǎn)成了一個(gè)類(lèi)數(shù)組,最后返回this,可用于鏈?zhǔn)秸{(diào)用。
if ( selector.nodeType ){//通過(guò)判斷該變量是否有nodeType屬性來(lái)確定是不是一個(gè)DOM節(jié)點(diǎn)
this.context = this[0] = selector;
this.length = 1;
return this;}
Function: $(fn) 就相當(dāng)于 $(document).ready(fn)
if ( jQuery.isFunction( selector ){//jquery內(nèi)部用來(lái)判斷一個(gè)對(duì)象是不是一個(gè)函數(shù)的方法 return rootjQuery.ready( selector );}
jQuery對(duì)象:
if ( selector.selector !== undefined ) {//如果改變了有select屬性則認(rèn)為該變量是jQ變量 this.selector = selector.selector; this.context = selector.context; return jQuery.makeArray( selector, this );}
其他任意類(lèi)型的值:將傳入的變量和jQuery對(duì)象合并成一個(gè)數(shù)組
return jQuery.makeArray( selector, this );
下面我們來(lái)看當(dāng) selector 為一個(gè)字符串時(shí)是如何進(jìn)行處理的:
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {//匹配單標(biāo)簽 match = [ null, selector, null ]; } else { match = rquickExpr.exec( selector ); } if ( match && (match[1] || !context) ) { //如果是字符串是html標(biāo)簽 if ( match[1] ) { jQuery.merge( this, jQuery.parseHTML(match[1]) ); //先通過(guò)parseHTML將字符串轉(zhuǎn)換成DOM對(duì)象的數(shù)組,然后通過(guò)merge將DOM對(duì)象的數(shù)組合并到this上。 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { 如果傳入的是單標(biāo)簽,且第二個(gè)參數(shù)是一個(gè)純對(duì)象,例如: $("",{"id":"box", "class":"red"})//則把后面對(duì)象的屬性一一添加到創(chuàng)建的這個(gè)DOM節(jié)點(diǎn)的屬性上。 //現(xiàn)在知道了通過(guò)$不僅可以創(chuàng)建標(biāo)簽,還能在創(chuàng)建單標(biāo)簽的時(shí)候直接在后面寫(xiě)屬性。 } } else { //如果是"#id",直接通過(guò)js的原生方法getElementById獲取DOM節(jié)點(diǎn) elem = document.getElementById( match[2] ); } //后面的情況都是通過(guò)find方法來(lái)找復(fù)雜的選擇器。例如selector是一個(gè)".ClassName" //具體過(guò)程為jQuery.fn.find->jQuery.find->Sizzle //最后會(huì)調(diào)用Sizzle方法,這是jQuery選擇器的核心方法,是一個(gè)獨(dú)立的引擎,等到了后面我看懂了再告訴大家吧 (逃 } else if ( !context || context.jquery ) { return ( context || rootjQuery ).find( selector ); } else { return this.constructor( context ).find( selector ); }看這段代碼前我們要先弄懂match到底是什么東西
rquickExpr = /^(?:s*(<[wW]+>)[^>]*|#([w-]*))$/; (75行) match = rquickExpr.exec( selector ); (116行)exec方法用于正則匹配,返回一個(gè)數(shù)組,第一個(gè)元素是匹配到的字符串,后面的元素為匹配子項(xiàng),具體用法。
舉個(gè)栗子:
var rquickExpr = /^(?:s*(<[wW]+>)[^>]*|#([w-]*))$/; console.log( match = rquickExpr.exec( "" ) ); // ["
", "
", undefined] console.log( match = rquickExpr.exec( "#id" ) ); // ["#id", undefined, "id"]
現(xiàn)在我們知道了,match其實(shí)就是存儲(chǔ)了字符串含義的數(shù)組,不得不感嘆這是人想出來(lái)的嗎。正則懵逼。
如果match[1]存在就代表是html標(biāo)簽
如果match[2]存在就代表是id名
如果兩種情況都沒(méi)有匹配到的話(huà),表示這是一個(gè)復(fù)雜選擇器,具體的實(shí)現(xiàn)是jQuery內(nèi)部的Sizzle方法來(lái)實(shí)現(xiàn),這個(gè)方法有兩千行左右,可謂是jQuery的核心,而且jQuery把這個(gè)方法也當(dāng)成了一個(gè)多帶帶的庫(kù),如果覺(jué)得jQuery太大,只會(huì)用到選擇器部分的功能,感興趣的話(huà)可以在Sizzle官網(wǎng) 下載
可以看到我們平時(shí)調(diào)用 $() 的時(shí)候很爽,又能當(dāng)選擇器又能創(chuàng)節(jié)點(diǎn),但是不知道這后面的實(shí)現(xiàn)方法原來(lái)這么復(fù)雜,還真是用起來(lái)越方便的東西實(shí)現(xiàn)越復(fù)雜。
恩,樓上說(shuō)的對(duì) -。-
感興趣的話(huà)可以看看我的github,不妨給個(gè)star。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/86700.html
摘要:的緩存機(jī)制來(lái)看看中提高的數(shù)據(jù)緩存機(jī)制,有兩個(gè)函數(shù),分別是和,可以看出來(lái),一個(gè)是在對(duì)象上,一個(gè)是在生成的對(duì)象上。而且從源碼來(lái)看,的緩存機(jī)制自帶清內(nèi)存操作,更是錦上添花呀。參考源碼分析數(shù)據(jù)緩存本文在上的源碼地址,歡迎來(lái)。 歡迎來(lái)我的專(zhuān)欄查看系列文章。 不打算介紹 deferred,或者放到后面以后去介紹,因?yàn)槲覍?duì)于 js 的異步存在著恐懼,看了半天代碼,發(fā)現(xiàn),用挺好用的,一看源碼,全傻眼了...
摘要:的指向的是對(duì)象,所以此時(shí)擴(kuò)展的是對(duì)象,可以直接通過(guò)的方式調(diào)用。 寫(xiě)過(guò)jquery插件的人都知道可以通過(guò)jquery提供的extend可以對(duì)jquery對(duì)象進(jìn)行擴(kuò)展,而且該方法不僅可以對(duì)jquery對(duì)象擴(kuò)展,還能給一個(gè)對(duì)象添加新的屬性和方法,這個(gè)在后面會(huì)介紹。 通過(guò)不同的方式調(diào)用extend擴(kuò)展的方法也不同: 通過(guò) $.extend() 擴(kuò)展的是靜態(tài)方法; 而通過(guò) $.fn.exten...
摘要:而在構(gòu)造函數(shù)中,返回了的實(shí)例對(duì)象。在中直接返回過(guò)的實(shí)例,這里的是的真正構(gòu)造函數(shù)最后對(duì)外暴露入口時(shí),將字符與對(duì)等起來(lái)。因此當(dāng)我們直接使用創(chuàng)建一個(gè)對(duì)象時(shí),實(shí)際上是創(chuàng)建了一個(gè)的實(shí)例,這里的正真構(gòu)造函數(shù)是原型中的方法。 showImg(https://segmentfault.com/img/remote/1460000008749398); 早幾年學(xué)習(xí)前端,大家都非常熱衷于研究jQuery源...
摘要:到目前為止,的貢獻(xiàn)者團(tuán)隊(duì)共名成員,多條,可想而知,是一個(gè)多么龐大的項(xiàng)目。參考源碼分析整體架構(gòu)源碼解析讀書(shū)筆記第二章構(gòu)造對(duì)象函數(shù)詳解本文在上的源碼地址,歡迎來(lái)。 歡迎來(lái)我的專(zhuān)欄查看系列文章。 決定你走多遠(yuǎn)的是基礎(chǔ),jQuery 源碼分析,向長(zhǎng)者膜拜! 我雖然接觸 jQuery 很久了,但也只是局限于表面使用的層次,碰到一些問(wèn)題,找到 jQuery 的解決辦法,然后使用。顯然,這種做法的...
摘要:本來(lái)想學(xué)習(xí)一下的源碼,但由于的源碼有多行,設(shè)計(jì)相當(dāng)復(fù)雜,所以決定從開(kāi)始,分析一個(gè)成熟的框架的代碼結(jié)構(gòu)及執(zhí)行步驟。同時(shí)發(fā)表在我的博客源碼分析代碼結(jié)構(gòu) 本來(lái)想學(xué)習(xí)一下jQuery的源碼,但由于jQuery的源碼有10000多行,設(shè)計(jì)相當(dāng)復(fù)雜,所以決定從zepto開(kāi)始,分析一個(gè)成熟的框架的代碼結(jié)構(gòu)及執(zhí)行步驟。 網(wǎng)上也有很多zepto的源碼分析,有的給源碼添加注釋?zhuān)械恼勁cjQuery的不同,...
閱讀 3200·2021-09-06 15:02
閱讀 2247·2019-08-30 15:48
閱讀 3443·2019-08-29 11:08
閱讀 3285·2019-08-26 13:55
閱讀 2443·2019-08-26 13:35
閱讀 3165·2019-08-26 12:11
閱讀 2601·2019-08-26 11:48
閱讀 888·2019-08-26 11:42