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