在大部分编程语言中, 循环语句消耗了大部分时间
而循环语句又是十分重要的编程模式
在我们JavaScript中, 有四种循环类型
for循环
while循环
do-while循环
for-in循环
其中前三种循环在其他语言也很常见
for-in循环对于在学校学过C/C++的同学来说也许很新鲜
它每次迭代的同时会搜索实例和原型属性, 所以它每次迭代便会产生更多的开销
for-in循环最终只有其他三种类型速度的1/7
所以, 除非我们明确需要迭代一个属性数量未知的对象, 否则我们应尽量避免使用for-in
更不要用for-in循环去遍历数组
我们可以这样去迭代一个明确的对象
var props = ['prop1', 'prop2'], i = 0;while(i < props.length){ fn(obj[props[i++]]); }
这段代码根据对象中的属性, 创建一个对象属性的数组, 然后通过while循环来遍历属性列表并处理对应属性值
这样就可以不用查找对象的每一个属性, 减少了循环的开销
上面做法的前提是对象内部的属性是已知的
如果我们不知道对象内部的实现
还要处理对象自身的属性,只能这样做了
for(var prop in obj){ if(obj.hasOwnProperty(prop)){ //... } }
代价是每次迭代都要判断这个属性是不是对象自己的属性而不是继承来的
除了for-in以外, 其他的循环性能都差不多, 所以使用的时候应该去考虑需求从而选择循环类型
相信刚学习编程的小伙伴都是介样写循环的
for(var i = 0; i < arr.length; i++){ fn(arr[i]); }
这个循环语句每进行一次迭代, 都要去查找arr中的length属性,这样很耗时
所以我们可以进行优化,
for(var i = 0, len = arr.length; i < len; i++){ fn(arr[i]); }
把数组长度值缓存到一个局部变量, 这样问题就解决了
while, do-while也是同理
根据数组长度, 很多浏览器中能节省大概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), 进一步提高了循环速度
最后补充几句
我们大家可能都用过一些数组方法比如arr.forEach()或者一些框架的迭代方法比如jQuery的$().each()去遍历数组,
这些方法对数组的每一个元素执行一个函数
尽管它们很方便, 但它们要比普通的循环要慢很多(调用了外部的方法)
在所有情况下, 基于循环的迭代比基于函数的迭代快大约8倍
所以我们在能使用普通循环(for,while,do-while)解决问题的时候尽量用这些普通循环
以上就是JavaScript循环语句的性能问题的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!