每次申明一個(gè)jQuery對(duì)象的時(shí)候,返回的是jQuery.prototype.init
成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)的開(kāi)發(fā),更需要了解用戶(hù),從用戶(hù)角度來(lái)建設(shè)網(wǎng)站,獲得較好的用戶(hù)體驗(yàn)。創(chuàng)新互聯(lián)多年互聯(lián)網(wǎng)經(jīng)驗(yàn),見(jiàn)的多,溝通容易、能幫助客戶(hù)提出的運(yùn)營(yíng)建議。作為成都一家網(wǎng)絡(luò)公司,打造的就是網(wǎng)站建設(shè)產(chǎn)品直銷(xiāo)的概念。選擇創(chuàng)新互聯(lián),不只是建站,我們把建站作為產(chǎn)品,不斷的更新、完善,讓每位來(lái)訪用戶(hù)感受到浩方產(chǎn)品的價(jià)值服務(wù)。
對(duì)象,很多人就會(huì)不明白,init明明是jQuery.fn的方法啊,實(shí)際上這里不是方法,而是init的構(gòu)造函數(shù),因?yàn)閖s的prototype對(duì)象可
以實(shí)現(xiàn)繼承,加上js的對(duì)象只是引用不會(huì)是拷貝,new
jQuery,new
jQuery.fn和new
jQuery.fn.init的子對(duì)象是一樣的,只是有沒(méi)有執(zhí)行到init的不同,這里就不講原因了,等下一篇再講為什么會(huì)是這樣。
當(dāng)我們使用選擇器的時(shí)候$(selector,content),就會(huì)執(zhí)行
init(selectot,content),我們看看inti中是怎樣執(zhí)行的:
復(fù)制代碼
代碼如下:
if
(
typeof
selector
==
"string"
)
{
//正則匹配,看是不是HTML代碼或者是#id
var
match
=
quickExpr.exec(
selector
);
//沒(méi)有作為待查找的
DOM
元素集、文檔或
jQuery
對(duì)象。
//selector是#id的形式
if
(
match
(match[1]
||
!context)
)
{
//
HANDLE:
$(html)
-
$(array)
//HTML代碼,調(diào)用clean補(bǔ)全HTML代碼
if
(
match[1]
){
selector
=
jQuery.clean(
[
match[1]
],
context
);
}
//
是:
$("#id")
else
{
//判斷id的Dom是不是加載完成
var
elem
=
document.getElementById(
match[3]
);
if
(
elem
){
if
(
elem.id
!=
match[3]
)
return
jQuery().find(
selector
);
return
jQuery(
elem
);//執(zhí)行完畢return
}
selector
=
[];
}
//非id的形式.在context中或者是全文查找
}
else{
return
jQuery(
context
).find(
selector
);
}
}
這里就說(shuō)明只有選擇器寫(xiě)成$(‘#id')的時(shí)候最快,相當(dāng)于執(zhí)行了一次
getElementById,后邊的程序就不用再執(zhí)行了。當(dāng)然往往我們需要的選擇器并不是這么簡(jiǎn)單,比如我們需要id下的CSS為className,
有這樣的寫(xiě)法$(‘#id.className')和$(‘#id').find(‘.className');這兩種寫(xiě)法的執(zhí)行結(jié)果都是一樣的,比
如div
id=”id”span
class=”className”/span/div,返回的肯定都是span
class=”className”/span,但是執(zhí)行的效率是完全不一樣的。
在分析一下上邊的代碼,如果不是$(‘#id')這樣的簡(jiǎn)單選擇器的話(huà),都會(huì)執(zhí)行find函
數(shù),那我們?cè)倏纯磃ind到底是做用的:
復(fù)制代碼
代碼如下:
find:
function(
selector
)
{
//在當(dāng)前的對(duì)象中查找
var
elems
=
jQuery.map(this,
function(elem){
return
jQuery.find(
selector,
elem
);
});
//下邊的代碼可以忽略,只是做一些處理
//這里應(yīng)用了js的正則對(duì)象的靜態(tài)方法test
//indexOf("..")需要了解一下xpath的語(yǔ)法,就是判斷selector中包含父節(jié)點(diǎn)的寫(xiě)法
//本意就是過(guò)濾數(shù)組的重復(fù)元素
return
this.pushStack(
/[^+]
[^+]/.test(
selector
)
||
selector.indexOf("..")
-1
?
jQuery.unique(
elems
)
:
elems
);
}
如果這樣寫(xiě)$(‘#id
.className'),就會(huì)執(zhí)行到擴(kuò)展的find(‘#id
.className',document),因?yàn)楫?dāng)前的this是document的jQuery數(shù)組,那我們?cè)诳纯磾U(kuò)展的find他的實(shí)現(xiàn),代碼比較
多,就不列出來(lái),總之就是從第二個(gè)參數(shù)傳遞進(jìn)行的dom第一個(gè)子節(jié)點(diǎn)開(kāi)始找,遇見(jiàn)#比對(duì)id,遇見(jiàn).比對(duì)ClassName,還有:+-等處理。
那我們要優(yōu)化,是不是就要想辦法讓第二個(gè)參數(shù)context的范圍最小,那樣遍歷是不是就很少了?
如果我們這樣寫(xiě)$(‘#id').find(‘.className'),那程序只這樣執(zhí)行
的,第一次init的時(shí)候執(zhí)行一步getElementById,就return了,接著執(zhí)行
find(‘.className',divDocument),divDocument就是我們第一次選擇的是div標(biāo)簽,如果document下有很
多dom對(duì)象的時(shí)候,這次只遍歷divDocument是不是少了很多次,而且在第一次選擇id的速度也要比遍歷快的多。
現(xiàn)在大家應(yīng)該是明白了吧。就是說(shuō)第一層選擇最好是ID,而是簡(jiǎn)單選擇器,目的就是定義范圍,
提高速度,這次就說(shuō)這些,選擇寫(xiě)法的優(yōu)化,其他的優(yōu)化,下次再說(shuō)。
jquery是javascript的一個(gè)插件,所以說(shuō)jquery的原理就是封裝javascript;
方法添加可以參考一些jquery插件,例如:resizableColumns,實(shí)現(xiàn)方法類(lèi)似下面:
$.fn.Plugname = function(options) {
}
jquery是javascript的一個(gè)類(lèi)庫(kù),說(shuō)到底jquery就是javascript jquery主要是用來(lái)簡(jiǎn)化javascript的各種操作以及解決各種瀏覽器之間的兼容性 用jquery能辦到的用javascript都能辦到。
這段時(shí)間在學(xué)習(xí)研究jQuery源碼,受益于jQuery日益發(fā)展強(qiáng)大,研究jQuery的大牛越來(lái)越多,學(xué)習(xí)的資料也比前兩年好找了,有很多非常不錯(cuò)的資源,如高云的jQuery1.6.1源碼分析系列。這些教程非常細(xì)致的分析了jQuery內(nèi)部原理和實(shí)現(xiàn)方式,對(duì)學(xué)習(xí)和理解jQuery有非常大的幫助。但是個(gè)人認(rèn)為很多教程對(duì)jQuery的整體結(jié)果把握不足,本人試圖從整體來(lái)闡述一下jQuery的內(nèi)部實(shí)現(xiàn)。
大家知道,調(diào)用jQuery有兩種方式,一種是高級(jí)的實(shí)現(xiàn),通過(guò)傳遞一個(gè)參數(shù)實(shí)現(xiàn)DOM選擇,如通過(guò)$(“h1″)選擇所有的h1元素,第二種是較為低級(jí)的實(shí)現(xiàn),如果通過(guò)$.ajax實(shí)現(xiàn)ajax的操作。那么,這兩種方式到底有何不同?用typeof函數(shù)檢測(cè)$(‘h1′)和$.ajax,類(lèi)型分別為object和function,稍微學(xué)過(guò)jQuery的都知道或者聽(tīng)過(guò)過(guò),前者返回的是一個(gè)jQuery對(duì)象,那么jQuery對(duì)象是什么,它和jQuery是什么關(guān)系呢?我們先來(lái)通過(guò)for(var
i
in
$(”))
document.write(i+”
:::”+$(“”)[i]+””);打印一下jQuery對(duì)象的屬性和對(duì)應(yīng)的值,可以看到它有100多個(gè)屬性,通過(guò)console輸入$(“*”)可以看到大部分屬性是繼承自jQuery原型的屬性,jQuery對(duì)象實(shí)際上是這樣一個(gè)對(duì)象:
所以我們來(lái)推測(cè),jQuery的實(shí)現(xiàn)可能是類(lèi)似這樣的:
function
jQuery(){
this[0]="Some
DOM
Element";
this[1]="Some
DOM
Element";
this[2]="Some
DOM
Element";
this.length=3;
this.prevObject="Some
Object";
this.context="Some
Object";
this.selector="Some
selector";
}
jQuery.prototype={
get:function(){},
each:function(){},
......
}
這些代碼通過(guò)new操作符就就能創(chuàng)建出擁有上述屬性的jQuery對(duì)象,但是實(shí)際上我們調(diào)用jQuery創(chuàng)建jQuery對(duì)象時(shí)并沒(méi)有使用new操作符,這是如何實(shí)現(xiàn)的呢?來(lái)看jQuery的實(shí)現(xiàn):
var
jQuery
=
function(
selector,
context
)
{
//
The
jQuery
object
is
actually
just
the
init
constructor
'enhanced'
return
new
jQuery.fn.init(
selector,
context,
rootjQuery
);
}
jQuery.fn=jQuery.prototype={
jquery:
core_version,
init:function(selector,context){
//some
code
return
this;
}
//some
code
there
//......
}
jQuery.fn.init.prototype=jQuery.fn;
這里有幾點(diǎn)做得非常巧妙的地方,第一點(diǎn)是通過(guò)jQuery原型屬性的init方法來(lái)創(chuàng)建對(duì)象來(lái)達(dá)到不用new創(chuàng)建對(duì)象的目的,第二點(diǎn)是對(duì)init方法內(nèi)this指向的處理。我們知道,通過(guò)調(diào)用init返回一個(gè)jQuery的實(shí)例,那么這個(gè)實(shí)例就必須要繼承jQuery.prototype的屬性,那么init里面這個(gè)this,
就繼承jQuery.prototype的屬性。但是init里面的this,受制于作用域的限制,并不能訪問(wèn)jQuery.prototype其它的屬性,jQuery通過(guò)一句'jQuery.fn.init.prototype=jQuery.fn'把它的原型指向jQuery.fn,這樣以來(lái),init產(chǎn)生的jQuery對(duì)象就擁有了jQuery.fn的屬性。
到這里,一個(gè)jQuery的基本原型就浮出水面了。這里有兩個(gè)對(duì)象,一個(gè)是jQuery這個(gè)構(gòu)造函數(shù),另外一個(gè)是這個(gè)構(gòu)造函數(shù)產(chǎn)生的對(duì)象(我們稱(chēng)之為jQuery對(duì)象,它和普通對(duì)象沒(méi)有什么區(qū)別),
如下關(guān)系圖:
可以看到j(luò)Query構(gòu)造函數(shù)和jQuery.prototype均有各自的屬性和方法,兩者的調(diào)用方法各不一樣,這兩個(gè)對(duì)象都有一個(gè)extend方法,都是用來(lái)擴(kuò)展自身的屬性和方法,在jQuery內(nèi)部,extend的實(shí)現(xiàn)實(shí)際是靠一樣的代碼,
將在后面的源碼分析中做以詳細(xì)的分析。
$ 是 JQuery 常用的一個(gè)回傳函數(shù),定義為 "選取" 英文是 selector 的縮寫(xiě)
例子︰
$.function();
就是 選取 JQuery 定義的 function() 執(zhí)行
$('input')
就是 選取 HTML 當(dāng)中全部的 input 標(biāo)簽
$('#abc')
就是 選取 HTML 當(dāng)中 ID 名稱(chēng)為 abc 的物件
$.fn.testing = function() {}
就是 選取 JQuery 內(nèi)核函數(shù) fn (函數(shù)) 回傳給 testing 這個(gè)名稱(chēng)、定義為一個(gè)功能 function()
var $=function(a){
var UNDEFINED;
if(a!=UNDEFINED!=null){
//調(diào)用有參方法
}else{
//調(diào)用無(wú)參方法
}
}
你這個(gè)好像不是這么這么說(shuō)的
$ 這是一個(gè)對(duì)象
$("選擇器")得到的是對(duì)象的實(shí)例
$.function是在對(duì)象上的方法,不是對(duì)象實(shí)例的方法,這兩個(gè)是不一樣的
名稱(chēng)欄目:jQuery$原理,jquery工作原理
網(wǎng)頁(yè)網(wǎng)址:http://chinadenli.net/article20/dsdssjo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、域名注冊(cè)、標(biāo)簽優(yōu)化、網(wǎng)站收錄、虛擬主機(jī)、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
營(yíng)銷(xiāo)型網(wǎng)站建設(shè)知識(shí)