jquery的each比原生的for循環(huán)慢很多?。槭裁??
創(chuàng)新互聯(lián)是一家專業(yè)提供港口企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計、成都網(wǎng)站設(shè)計、html5、小程序制作等業(yè)務(wù)。10年已為港口眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。
其實查看jQuery的源代碼,發(fā)現(xiàn)each的代碼很簡單,但為什么性能和原生的for循環(huán)相差幾十倍呢?
jquery的each的核心代碼
for?(;?i??length;?i++)?{??
value?=?callback.call(obj[i],?i,?obj[i]);??
if?(value?===?false)?{??
break;??
}??
}
看著很簡單,但為什么會慢很多呢?
編寫測試代碼如下:
var?length=300000;??
function?GetArr()?{??
var?t?=?[];??
for?(var?i?=?0;?i??length;?i++)?{??
t[i]?=?i;??
}??
return?t;??
}??
function?each1(obj,?callback)?{??
var?i?=?0;??
var?length?=?obj.length??
for?(;?i??length;?i++)?{??
value?=?callback(i,?obj[i]);??
/*?if?(?value?===?false?)?{去掉了判斷?
break;?
}*/??
}??
}??
function?each2(obj,?callback)?{??
var?i?=?0;??
var?length?=?obj.length??
for?(;?i??length;?i++)?{??
value?=?callback(i,?obj[i]);/*去掉了call*/??
if?(value?===?false)?{??
break;??
}??
}??
}??
function?each3(obj,?callback)?{??
var?i?=?0;??
var?length?=?obj.length??
for?(;?i??length;?i++)?{??
value?=?callback.call(obj[i],?i,?obj[i]);/*自己寫的call*/??
if?(value?===?false)?{??
break;??
}??
}??
}??
function?Test1()?{??
var?t?=?GetArr();??
var?date1?=?new?Date().getTime();??
var?lengtharr?=?t.length;??
var?total?=?0;??
each1(t,?function?(i,?n)?{??
total?+=?n;??
});??
var?date12?=?new?Date().getTime();??
console.log("1Test"?+?((date12?-?date1)));??
}??
function?Test2()?{??
var?t?=?GetArr();??
var?date1?=?new?Date().getTime();??
var?total?=?0;??
each2(t,?function?(i,?n)?{??
total?+=?n;??
});??
var?date12?=?new?Date().getTime();??
console.log("2Test"?+?((date12?-?date1)));??
}??
function?Test3()?{??
var?t?=?GetArr();??
var?date1?=?new?Date().getTime();??
var?total?=?0;??
each3(t,?function?(i,?n)?{??
total?+=?n;??
});??
var?date12?=?new?Date().getTime();??
console.log("3Test"?+?((date12?-?date1)));??
}??
function?Test4()?{??
var?t?=?GetArr();??
var?date1?=?new?Date().getTime();??
var?total?=?0;??
$.each(t,?function?(i,?n)?{??
total?+=?n;??
});??
var?date12?=?new?Date().getTime();??
console.log("4Test"?+?((date12?-?date1)));??
}
運(yùn)行測試,發(fā)現(xiàn),第一個和第二個相差不是很大,這說明由于break這個判斷導(dǎo)致的性能差異很少,
但第二個和第三個,第四個偏差就就不止一倍了,而第二個和第三個唯一的區(qū)別就是調(diào)用了call,看來call會導(dǎo)致性能損失,因為call會切換上下文,當(dāng)然jQuery的each慢還有其他原因,它還在循環(huán)中調(diào)用了其他的方法,call只是一個原因罷了。
因此可以說call,和apply都是js中比較消耗性能的方法,在性能要求嚴(yán)格時,建議少用。
在jquery中的each有兩種用法,分別是$.each()和$(selector).each(); $.each()與$(selector).each()不同, 后者專用于jquery對象的遍歷, 前者可用于遍歷任何的集合(無論是數(shù)組或?qū)ο?,如果是數(shù)組,回調(diào)函數(shù)每次傳入數(shù)組的索引和對應(yīng)的值
each()就是循環(huán),給你例子吧,比如你的頁面只有 3對p標(biāo)簽p1/pp2/pp3/p$("p").each(function(i){//這樣寫它就是循環(huán)三次,其中function中的i就是指索引alert(i);//彈出循環(huán)到當(dāng)前p的索引,索引從0開始,你可以試試,執(zhí)行程序看效果就是最好的理解alert($(this).text());//彈出循環(huán)到當(dāng)前p的文本});
在jquery中,遍歷對象和數(shù)組,經(jīng)常會用到$().each和$.each(),兩個方法。兩個方法是有區(qū)別的,從而這兩個方法在針對不同的操作上,顯示了各自的特點(diǎn)。
$().each,對于這個方法,在dom處理上面用的較多。如果頁面有多個input標(biāo)簽類型為checkbox,對于這時用$().each來處理多個checkbook,例如:
$(“input[name=’ch’]”).each(function(i){
if($(this).attr(‘checked’)==true)
{
//一些操作代碼
}
回調(diào)函數(shù)是可以傳遞參數(shù),i就為遍歷的索引。
對于遍歷一個數(shù)組,用$.each()來處理,簡直爽到了極點(diǎn)。例如:
$.each([{“name”:”limeng”,”email”:”xfjylimeng”},{“name”:”hehe”,”email”:”xfjylimeng”},function(i,n)
{
alert(“索引:”+i,”對應(yīng)值為:”+n.name);
});
參數(shù)i為遍歷索引值,n為當(dāng)前的遍歷對象.
var arr1 = [ “one”, “two”, “three”, “four”, “five” ];
$.each(arr1, function(){
alert(this);
});
輸出:one two three four five
var arr2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
$.each(arr2, function(i, item){
alert(item[0]);
});
輸出:1 4 7
var obj = { one:1, two:2, three:3, four:4, five:5 };
$.each(obj, function(key, val) {
alert(obj[key]);
});
輸出:1 2 3 4 5
在jQuery里有一個each方法,用起來非常的爽,不用再像原來那樣寫for循環(huán),jQuery源碼里自己也有很多用到each方法。
其實jQuery里的each方法是通過js里的call方法來實現(xiàn)的。
下面簡單介紹一下call方法。
call這個方法很奇妙,其實官方的說明是:“調(diào)用一個對象的一個方法,以另一個對象替換當(dāng)前對象?!本W(wǎng)上更多的解釋是變換上下文環(huán)境,也有說是改變上下文this指針。
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
參數(shù)
thisObj
可選項。將被用作當(dāng)前對象的對象。
arg1, arg2, , argN
可選項。將被傳遞方法參數(shù)序列。
說明
call 方法可以用來代替另一個對象調(diào)用一個方法。call 方法可將一個函數(shù)的對象上下文從初始的上下文改變?yōu)橛?thisObj 指定的新對象。
引用網(wǎng)上有一個很經(jīng)典的例子
Js代碼
function add(a,b)
{
alert(a+b);
}
function sub(a,b)
{
alert(a-b);
}
add.call(sub,3,1);
用 add 來替換 sub,add.call(sub,3,1) == add(3,1) ,所以運(yùn)行結(jié)果為:alert(4);
注意:js 中的函數(shù)其實是對象,函數(shù)名是對 Function 對象的引用。
具體call更深入的就不在這里提了。
下面提一下jQuery的each方法的幾種常用的用法
Js代碼
var arr = [ “one”, “two”, “three”, “four”];
$.each(arr, function(){
alert(this);
});
//上面這個each輸出的結(jié)果分別為:one,two,three,four
var arr1 = [[1, 4, 3], [4, 6, 6], [7, 20, 9]]
$.each(arr1, function(i, item){
alert(item[0]);
});
//其實arr1為一個二維數(shù)組,item相當(dāng)于取每一個一維數(shù)組,
//item[0]相對于取每一個一維數(shù)組里的第一個值
//所以上面這個each輸出分別為:1 4 7
var obj = { one:1, two:2, three:3, four:4};
$.each(obj, function(key, val) {
alert(obj[key]);
});
//這個each就有更厲害了,能循環(huán)每一個屬性
//輸出結(jié)果為:1 2 3 4
遍歷一個jQuery對象,為每個匹配元素執(zhí)行一個函數(shù)。
ul????
lifoo/li????
libar/li
/ul
$(?"li"?).each(function(?index?)?{??
console.log(?index?+?":?""?+?$(this).text()?);
});
//或者一個數(shù)組,集合,map
$.each(集合,function(){
console.log(?集合.name+?":?""?+集合.age?);
});