首先先上模擬代碼
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
var result = createData();
function createData() {
var result = [];
for (var index = 0; index < 900000; index++) {
result.push(index);
}
return result;
}
/**
* 模擬jquery的each循環
*/
function each(arr, fn) {
for (var index = 0, len = arr.length; index < len; index++) {
fn.call(null, arr[index], index, arr);
}
}
var start = new Date().getTime();
var testNum = 3;
// each循環
each(result, function(item) {
testNum += item;
});
var end = new Date().getTime();
// IE8下1530左右
console.log(end - start);
start = new Date().getTime();
testNum = 3;
// normal循環
for (var index = 0, len = result.length; index < len; index++) {
testNum += result[index];
}
end = new Date().getTime();
// IE8下450左右
console.log(end - start);
if (Array.prototype.forEach) {
start = new Date().getTime();
testNum = 3;
result.forEach(function(item) {
testNum += item;
});
end = new Date().getTime();
// Chrome下60以上
console.log(end - start);
}
</script>
</head>
<body>
</body>
</html>
由於Firefox實在是太快了,所以將900000改成11900000,提高兩個數量級。得出的結果是
jquery each:42
native loop:41
html5 foreach:40
在chrome下,11900000次循環
jquery each:260
native loop:92
html5 foreach:771
在ie8下,900000次循環,降低兩個數量級
jquery each:1530
native loop:450
html5 foreach:不支持
Why is this result?
從js的實現原理上說,每段function在執行的時候,都會生成一個active object和一個scope chain。
所有當前function內部包含的對象都會放入active object中。
比如function F() {var a = 1;}
這個a就被放入了當前active object中,並且將active object放入了scope chain的頂層,index爲0
看下這個例子:
var a = 1; function f1() { var b = 2; function f2() { var c = 3 + b + a; } f2(); } f1();
當f2執行的時候,變量c像之前的那個例子那樣被放入scope chain 的index0這個位置上,但是變量b卻不是。瀏覽器要順着scope chain往上找,到scope chain爲1的那個位置找到了變量b。這條法則用在變量a上就變成了,要找到scope chain 的index=2的那個位置上才能找到變量a。
總結一句話:調用位於當前function越遠的變量,瀏覽器調用越是慢。因爲scope chain要歷經多次遍歷。
因此,由於jquery each循環在調用的時候比原生的loop多套了一層function。他的查找速度肯定比原生loop要慢。而firefox的原生forEach循環在內部做了優化,所以他的調用速度幾乎和原生loop持平。但是可以看到,在chrome上,html5的原生foreach是最慢的。可能是因爲內部多嵌套了幾層function。
Conclusion
對於效率爲首要目標的項目,務必要用native loop。