[转] 怎样快速而优雅地遍历 JavaScript 数组

咱们通常用循环来遍历数组,而循环一直是 JavaScript 性能问题的常见来源,有时循环用得很差会严重下降代码的运行速度。例如,遍历数组时,咱们会很天然地写出下面这种代码:数组

// 未优化的代码1
var array = [0,1,2,3,4,5,6,7,8,9];性能

// for-in 循环
for (var val in array) {
    fn(val); -> should be fn(array[val])
}优化

还有这一种常见写法:spa

// 未优化的代码2
var array = [0,1,2,3,4,5,6,7,8,9];对象

// for 循环
for (var i=0; i < array.length; i++) {
    fn(array[i]);
}ip

这两个方法看上去彷佛不错,并且语义上也很容易理解。可是这两个方法都有性能问题:get

“未优化的代码1”中,for-in 须要分析出 array 的每一个属性,这个操做的性能开销很大,用在 key 已知的数组上是很是不划算的。因此尽可能不要用 for-in,除非你不清楚要处理哪些属性,例如 JSON 对象这样的状况。class

“未优化的代码2”中,循环每执行一次,都要检查一次 array.length 的值,读属性要比读局部变量慢,尤为是当 array 里存放的都是 DOM 元素(像 array = document.getElementByClassName("class");),由于每次读 array.length 都要扫描一遍页面上 class="class" 的元素,速度更是慢得抓狂。变量

假如你的任务是从页面上 100 个复选框中,找出选中的复选框的 value,并把它们放入一个数组的话,在 IE 上可能得花上半秒才能完成。结果就是,用户在列表里选择了本身要的项目,点击提交后起码要过半秒才会有反应,直观感受就是很卡。循环

咱们毫不能接受这样的结果,因此咱们须要加快循环终止条件的计算速度。先把数组的长度先查出来,存进一个局部变量,那么循环的速度将会大大提升:

// 快速的代码
var array = [0,1,2,3,4,5,6,7,8,9];

// for 循环
var length = array.length;
for (var i=0; i < length; i++) {
    fn(array[i]);
}

如今只须要读取一次 array.length 的值,遍历数组的过程大大加快了。

不过咱们还可让它更快。若是循环终止条件不须要进行比较运算,那么循环的速度还能够更快:

// 最快的代码
var array = [0,1,2,3,4,5,6,7,8,9];

// for 循环
for (var i = array.length; i--;) {
    fn(array[i]);
}

把数组下标改为向 0 递减,循环终止条件只须要判断 i 是否为 0 就好了。由于循环增量和循环终止条件结合在一块儿,因此能够写成更简单的 while 循环:

// 最快且优雅的代码
var array = [0,1,2,3,4,5,6,7,8,9];

// while 循环
var i = array.length;
while (i--) {     fn(array[i]); }

相关文章
相关标签/搜索