建议29:准确使用循环体(1)
1.选择正确的循环体
在大多数编程语言中,代码执行时间多数消耗在循环的执行上。在一系列编程模式中,循环是最常用的模式之一,因此也是提高性能必须关注的地方之一。理解JavaScript 中循环对性能的影响至关重要,因为死循环或长时间运行的循环会严重影响用户体验。JavaScript定义了4种类型的循环:
第一种循环是标准的for循环,与C语言使用同样的语法:
- for (var i=0; i < 10; i++){
- //循环体
- }
for循环是最常用的循环结构,它由4部分组成:初始化体、前测条件、后执行体、循环体。当遇到一个for循环时,初始化体首先执行,然后进入前测条件。如果前测条件的计算结果为true,则执行循环体,然后运行后执行体。for循环在封装上的直接性是开发者喜欢使用它的原因之一。
第二种循环是while循环。while 循环是一个简单的前测循环,由一个前测条件和一个循环体构成:
- var i = 0;
- while(i < 10){
- //循环体
- i++;
- }
在执行循环体之前,先对前测条件进行计算。如果计算结果为true,那么就执行循环体;否则将跳过循环体。任何for 循环都可以写成while 循环,反之亦然。
第三种循环是do while循环。do while 循环是JavaScript中唯一一种后测试的循环,它包括两部分:循环体和后测条件。
- var i = 0;
- do {
- //循环体
- } while (i++ < 10);
在一个do while 循环中,循环体至少运行一次,后测条件决定循环体是否应再次执行。
第四种循环是for in 循环。此循环有一个非常特殊的用途:可以枚举任何对象的命名属性。
- for (var prop in object){
- //循环体
- }
每次执行循环,属性都被对象属性的名字(一个字符串)填充,直到所有的对象属性遍历完成才返回。返回的属性包括对象的实例属性和对象从原型链继承而来的属性。
提高循环性能的起点是选用哪种循环。在JavaScript 提供的4种循环类型中,只有for in循环执行速度比其他循环明显要慢。
由于每次迭代操作要搜索实例或原型的属性,for in循环每次迭代都要付出更多开销,因此它比其他类型循环执行速度慢一些。在同样的循环迭代操作中,其他类型循环执行速度比for in 循环快7 倍之多,因此推荐这样做:除非需要对数目不详的对象属性进行操作,否则避免使用for in循环。例如,迭代遍历一个有限的、已知的属性列表,使用其他循环类型更快,具体的使用模式如下:
- var props = ["prop1", "prop2"],
- i = 0;
- while (i < props.length){
- process(object[props[i]]);
- }
此代码创建一个由成员和属性名构成的队列。while 循环用于遍历这几个属性并处理所对应的对象成员,而不是遍历对象的每个属性。此代码只关注感兴趣的属性,节约了循环时间。