在大部分编程语言中, 循环语句消耗了大部分时间
而循环语句又是十分重要的编程模式
在JavaScript中, 有四种循环类型
for循环, while循环, do-while循环, for-in循环
前三种循环在其他语言也很常见
for-in循环每次迭代同时会搜索实例或时原型属性, 所以它每次迭代会产生更多开销
for-in循环最终只有其他三种类型速度的1/7
所以, 除非我们明确需要迭代一个属性数量未知的对象, 否则我们应尽量避免使用for-in
更不要用for-in循环去遍历数组
var props = ['prop1', 'prop2'], i = 0; while(i < props.length){ fn(obj[props[i++]]); }
这段代码根据对象中的属性, 创建一个对象属性的数组, 然后通过while循环来遍历属性列表并处理对应属性值
这样就不用查找对象的每一个属性, 减少了循环的开销
除了for-in以外, 其他的循环性能都差不多, 所以使用的时候应该去考虑需求从而选择循环类型
还有就是刚学循环语句去遍历数组的时候, 大家都是这么写的
for(var i = 0; i < arr.length; i++){ fn(arr[i]); }这个循环语句每进行一次迭代, 都要去查找arr中的length属性,这样很耗时
所以我们可以进行优化,
for(var i = 0, len = arr.length; i < arr.len; i++){ fn(arr[i]); }把数组长度值缓存到一个局部变量, 这样问题就解决了
根据数组长度, 很多浏览器中能节省大概25%的运行时间
我们还可以颠倒数组顺序来略微提高性能
for(var i = items.length; i--;){ process(items[i]); }
var j = items.length; while(j--){ process(items[j]); }
var k = items.length - 1; do { process(items[k]); }while(k--);
这样做每次迭代控制条件从两次判断(迭代数是否小于总数, 是否为true)
减少为一次判断(是否为true), 进一步提高了循环速度
我们大家可能都用过数组方法forEach()
遍历数组,并对每一个元素执行一个函数
尽管它很方便, 但它要比普通的循环要慢一些(调用外部方法)
在所有情况下, 基于循环的迭代比基于函数的迭代快8倍