接下來言歸正傳.....說正經(jīng)的
由于$()函數(shù)返回的是一個包裹了原生dom對象數(shù)組的對象,并且在此對象原型上擴(kuò)展的函數(shù)都是為了操作原生的dom對象,所以少不了循環(huán)遍歷的操作,熟悉jquery庫的人都知道有個jQuery.each()函數(shù) ,大部分的涉及jquery對象的函數(shù)都會用到這個函數(shù): 簡單的實現(xiàn)應(yīng)該是形如這樣:
(再次重申,只是簡單的實現(xiàn)原理,不要考慮具體的功能性問題)
if (!window['$'])
window['$'] = window['jQuery'];
/*這里以上區(qū)域為上一篇文章的閉包內(nèi)的內(nèi)容
* 定義jQuery.each 根據(jù)傳入對象來執(zhí)行操作
* @param {Object} obj
* @param {Object} func
*簡單起見我只考慮了數(shù)組以及jQuery對象兩種情況,跟上一篇一樣,原理應(yīng)該是一致的
*/
window['jQuery']['each']=function(obj,func){
if(obj.constructor==Array){
for(var i=0;i<obj.length;i++){
func.call(obj[i],i,obj[i]);//可以看到傳入的func 應(yīng)該是形如function(i,item) i代表遍歷到的下標(biāo),item則代表在數(shù)組中遍歷到的對象
}
}else if(obj.elements&&obj.elements.constructor==Array){//這里采用了傳說的鴨子法則,而不是判定它是不是jQuery的實例 只要你有Array類型的elements我就對你進(jìn)行操作
for(var i=0;i<obj.elements.length;i++){
func.call(obj.elements[i],i,obj.elements[i]);//可以看到傳入的func 應(yīng)該是形如function(i,item) i代表遍歷到的下標(biāo),item則代表在數(shù)組中遍歷到的對象
}
}else{
return null;
}
}
在這個函數(shù)的基礎(chǔ)之上可以開始擴(kuò)充_jQuery的prototype了;首先就是先寫一個包裝器對象可以直接調(diào)用的方法each:(這個并不是重復(fù)),然后通過調(diào)用這個each函數(shù)可以完成對對象數(shù)組的遍歷,
比如:
//寫在閉包內(nèi) 注意將昨天命名沖突了的jQuery構(gòu)造函數(shù)名稱改為_jQuery
_jQuery.prototype = {
each: function(func){
jQuery.each(this, func);
return this;
},
attr: function(key, value){
//示例定義這個set與get于一身的操作屬性的函數(shù)
if (arguments.length == 0) {
return null;
}
else
if (arguments.length == 1) {
return this.elements[0].getAttribute(key);
}
else if(arguments.length == 2){
this.each(function(i, item){
//這里可以看到重新定義each方法的好處一:精簡代碼 ,二:在內(nèi)部函數(shù)中this仍然是指向調(diào)用的包裝器對象而不是window
item.setAttribute(key, value);
})
}
}
/*
* 這里可以開始引入其他方法
*/
}
接下來做幾個簡單的測試:(還是上一篇的測試html)
輸入:
var k= $('#header');
consoles.write(k.attr('title','test title!').attr('title')); //鏈?zhǔn)秸{(diào)用
輸出:
test title!
依此類推,依靠each方法可以有效的擴(kuò)充包裝器的方法。
之前說的影響到j(luò)Query的鏈?zhǔn)秸{(diào)用的要點有三點,事實事后一想完全不是那么簡單,jQuery內(nèi)部代碼的維護(hù)感覺并不比有些庫好,雖然至少在操作上來講使用起來非常順手(當(dāng)然只是針對一些小的操作,大的項目一時也無法接觸到,也不好跟著一些大大人云亦云). 不過就算僅僅從遍歷操作來看, 也可以看到其實這個庫只能依托細(xì)化的插件,擴(kuò)充下去只會顯得臃腫不堪。
注:如果有仔細(xì)剖析了jquery源碼的人肯定會對我如此拙劣的所謂的實現(xiàn)嗤之以鼻,我的確只是看了幾本比如javascript dom高級程序設(shè)計 以及javascript 高級程序設(shè)計 設(shè)計模式等好書之后有感而發(fā)而已,可能跟具體的jquery的實現(xiàn)有很大的落差,可以的話希望可以指正一下。