改善JavaScript程序的188个建议2130.docx

上传人:b****3 文档编号:4644997 上传时间:2023-05-07 格式:DOCX 页数:28 大小:59.07KB
下载 相关 举报
改善JavaScript程序的188个建议2130.docx_第1页
第1页 / 共28页
改善JavaScript程序的188个建议2130.docx_第2页
第2页 / 共28页
改善JavaScript程序的188个建议2130.docx_第3页
第3页 / 共28页
改善JavaScript程序的188个建议2130.docx_第4页
第4页 / 共28页
改善JavaScript程序的188个建议2130.docx_第5页
第5页 / 共28页
改善JavaScript程序的188个建议2130.docx_第6页
第6页 / 共28页
改善JavaScript程序的188个建议2130.docx_第7页
第7页 / 共28页
改善JavaScript程序的188个建议2130.docx_第8页
第8页 / 共28页
改善JavaScript程序的188个建议2130.docx_第9页
第9页 / 共28页
改善JavaScript程序的188个建议2130.docx_第10页
第10页 / 共28页
改善JavaScript程序的188个建议2130.docx_第11页
第11页 / 共28页
改善JavaScript程序的188个建议2130.docx_第12页
第12页 / 共28页
改善JavaScript程序的188个建议2130.docx_第13页
第13页 / 共28页
改善JavaScript程序的188个建议2130.docx_第14页
第14页 / 共28页
改善JavaScript程序的188个建议2130.docx_第15页
第15页 / 共28页
改善JavaScript程序的188个建议2130.docx_第16页
第16页 / 共28页
改善JavaScript程序的188个建议2130.docx_第17页
第17页 / 共28页
改善JavaScript程序的188个建议2130.docx_第18页
第18页 / 共28页
改善JavaScript程序的188个建议2130.docx_第19页
第19页 / 共28页
改善JavaScript程序的188个建议2130.docx_第20页
第20页 / 共28页
亲,该文档总共28页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

改善JavaScript程序的188个建议2130.docx

《改善JavaScript程序的188个建议2130.docx》由会员分享,可在线阅读,更多相关《改善JavaScript程序的188个建议2130.docx(28页珍藏版)》请在冰点文库上搜索。

改善JavaScript程序的188个建议2130.docx

改善JavaScript程序的188个建议2130

建议21:

推荐提高循环性能的策略

(1)

每次运行循环体时都会产生性能开销,增加总的运行时间,即使是循环体中最快的代码,累计迭代上千次,也将带来不小的负担。

因此,减少循环的迭代次数可获得显著的性能提升。

例如:

1.var iterations = Math.floor(items.length / 8), startAt = items.length % 8, i = 0; 

2.do { 

3.    switch(startAt) { 

4.        case 0:

 

5.            process(items[i++]); 

6.        case 7:

 

7.            process(items[i++]); 

8.        case 6:

 

9.            process(items[i++]); 

10.        case 5:

 

11.            process(items[i++]); 

12.        case 4:

 

13.            process(items[i++]); 

14.        case 3:

 

15.            process(items[i++]); 

16.        case 2:

 

17.            process(items[i++]); 

18.        case 1:

 

19.            process(items[i++]); 

20.    } 

21.    startAt = 0; 

22.} while (--iterations); 

在上面代码中,每次循环最多可调用process()函数8次。

循环迭代次数为元素总数除以8。

因为总数不一定是8的整数倍,所以startAt变量存放余数,指明第一次循环中应当执行多少次process()。

如果现在有12个元素,那么第一次循环将调用process()4次,第二次循环调用process()8次,用两次循环代替了12次循环。

在下面的代码中取消switch表达式,将余数处理与主循环分开。

1.var i = items.length % 8; 

2.while(i) { 

3.    process(items[i--]); 

4.} 

5.i = Math.floor(items.length / 8); 

6.while(i) { 

7.    process(items[i--]); 

8.    process(items[i--]); 

9.    process(items[i--]); 

10.    process(items[i--]); 

11.    process(items[i--]); 

12.    process(items[i--]); 

13.    process(items[i--]); 

14.    process(items[i--]); 

15.} 

虽然上面代码使用两个循环替代了先前的一个循环,但是在循环体中去掉了switch表达式,速度更快。

如果循环的迭代次数少于1000次,减少迭代次数的循环与普通循环相比可能只有微不足道的性能提升。

如果迭代次数超过1000次,比如在500000次迭代中,合理地减少循环的迭代次数可以使运行时间减少到普通循环的70%。

有两个因素影响到循环的性能:

每次迭代干什么。

迭代的次数。

通过减少这两者中的一个或全部(的执行时间),可以提高循环的整体性能。

如果一次循环需要较长时间来执行,那么多次循环将需要更长时间。

限制在循环体内进行耗时操作的数量是一个加快循环的好方法。

一个典型的数组处理循环可采用3种循环的任何一种。

最常用的代码如下:

1.//方法1 

2.for (var i=0; i < items.length; i++){ 

3.    process(items[i]); 

4.} 

5.//方法2 

6.var j=0; 

7.while (j < items.length){ 

8.    process(items[j++]); 

9.} 

10.//方法3 

11.var k=0; 

12.do { 

13.    process(items[k++]); 

14.} while (k < items.length); 

建议21:

推荐提高循环性能的策略

(2)

在每个循环中,每次运行循环体都要发生如下操作:

第1步,在控制条件中读一次属性(items.length)。

第2步,在控制条件中执行一次比较(i

第3步,比较操作,观察条件控制体的运算结果是不是true(i

第4步,一次自加操作(i++)。

第5步,一次数组查找(items[i])。

第6步,一次函数调用(process(items[i]))。

在这些简单的循环中,即使没有太多的代码,每次迭代都要进行这6步操作。

代码运行速度很大程度上由process()对每个项目的操作所决定,即便如此,减少每次迭代中操作的总数也可以大幅度提高循环的整体性能。

优化循环的第一步是减少对象成员和数组项查找的次数。

在大多数浏览器上,这些操作比访问局部变量或直接量需要更长时间。

例如,在上面代码中,每次循环都查找items.length,这是一种浪费,因为该值在循环体执行过程中不会改变,因此产生了不必要的性能损失。

我们可以简单地将此值存入一个局部变量中,在控制条件中使用这个局部变量,从而提高了循环性能,例如:

1.for (var i=0, len=items.length; i < len; i++){ 

2.    process(items[i]); 

3.} 

4.var j=0, count = items.length; 

5.while (j < count){ 

6.    process(items[j++]); 

7.} 

8.var k=0, num = items.length; 

9.do { 

10.    process(items[k++]); 

11.} while (k < num); 

这些重写后的循环只在循环执行之前对数组长度进行一次属性查询,使控制条件中只有局部变量参与运算,因此速度更快。

根据数组的长度,在大多数浏览器上总循环时间可以节省大约25%,在IE浏览器中可节省50%。

还可以通过改变循环的顺序来提高循环性能。

通常,数组元素的处理顺序与任务无关,可以从最后一个开始,直到处理完第一个元素。

倒序循环是编程语言中常用的性能优化方法,不过一般不太容易理解。

在JavaScript中,倒序循环可以略微提高循环性能,例如:

1.for (var i=items.length; i--; ){ 

2.    process(items[i]); 

3.} 

4.var j = items.length; 

5.while (j--){ 

6.    process(items[j]); 

7.} 

8.var k = items.length-1; 

9.do { 

10.    process(items[k]); 

11.} while (k--); 

在上面代码中使用了倒序循环,并且在控制条件中使用了减法。

每个控制条件只是简单地与零进行比较。

控制条件与true值进行比较,任何非零数字自动强制转换为true,而零等同于false。

实际上,控制条件已经从两次比较减少到一次比较。

将每次迭代中两次比较减少到一次可以大幅度提高循环速度。

通过倒序循环和最小化属性查询,可以看到执行速度比原始版本提升了50%~60%。

与原始版本相比,每次迭代中只进行如下操作:

第1步,在控制条件中进行一次比较(i==true)。

第2步,一次减法操作(i--)。

第3步,一次数组查询(items[i])。

第4步,一次函数调用(process(items[i]))。

新循环的每次迭代中减少两个操作,随着迭代次数的增长,性能将显著提升。

建议22:

少用函数迭代

ECMA-262v4为本地数组对象新增加了一个forEach方法。

此方法遍历一个数组的所有成员,并且在每个成员上执行一个函数。

在每个元素上执行的函数作为forEach()的参数传进去,并在调用函数时接收3个参数:

数组项的值、数组项的索引、数组自身。

例如:

1.items.forEach(function(value, index, array){ 

2.    process(value); 

3.}); 

forEach在Firefox、Chrome和Safari等浏览器中为原生函数。

另外,forEach在大多数JavaScript库中都有等价实现,例如:

1.//YUI 3 

2.Y.Array.each(items, function(value, index, array){ 

3.    process(value); 

4.}); 

5.//jQuery 

6.jQuery.each(items, function(index, value){ 

7.    process(value); 

8.}); 

9.//Dojo 

10.dojo.forEach(items, function(value, index, array){ 

11.    process(value); 

12.}); 

13.//Prototype 

14.items.each(function(value, index){ 

15.    process(value); 

16.}); 

尽管基于函数的迭代使用起来非常便利,但是比基于循环的迭代要慢一些。

每个数组项要关联额外的函数调用是造成速度慢的主要原因。

在所有情况下,基于函数的迭代占用时间是基于循环的迭代的8倍,因此在非特殊需求下,不建议使用函数迭代。

建议23:

推荐提高条件性能的策略

与循环相似,条件表达式决定JavaScript运行流的走向。

与其他语言一样,JavaScript也采用了if和switch两种条件结构。

由于不同浏览器针对流程控制进行了不同的优化,因此两者在性能上并没有特别大的差异,主要还是根据需求形式进行分析和选择:

条件数量较大,建议选择switch结构,而不是if结构,这样可以使代码更易读;如果条件较少时,建议选择if结构。

1.//条件少 

2.if(found) { 

3.    //执行代码 

4.} else { 

5.    //执行代码 

6.} 

7.//条件多 

8.switch (color) { 

9.    case "red":

 

10.        //执行代码 

11.        break; 

12.    case "blue":

 

13.        //执行代码 

14.        break; 

15.    case "brown":

 

16.        //执行代码 

17.        break; 

18.    case "black":

 

19.        //执行代码 

20.        break; 

21.    default:

 

22.        //执行代码 

23.} 

事实证明,在大多数情况下,switch比if运行更快,但是只有当条件体数量很大时才明显更快。

switch与if的主要性能区别在于:

当条件体增加时,if性能负担增加的程度比switch更大。

因此,从性能方面考虑,如果条件体较少,应使用if;如果条件体较多,应使用switch。

一般来说,if适用于判断两个离散的值或几个不同的值域。

如果判断多于两个离散值,那么switch将是更理想的选择。

建议24:

优化if逻辑

(1)

逻辑顺序体现了人的思维的条理性和严密性。

合理的顺序可以提升解决问题的品质,相反,混乱的顺序很容易导致各种错误的发生。

在分支结构中经常需要面临各种优化逻辑顺序的问题。

人在思考问题时,一般总会对各种最可能发生的情况做好准备,这叫做“有备而来”。

分支结构中各种条件根据情况的先后、轻重来排定顺序。

如果把最可能的条件放在前面,把最不可能的条件放在后面,这样程序在执行时总会按照代码先后顺序逐一检测所有条件,直到发现匹配的条件时才停止继续检测。

如果把最可能的条件放在前面,就等于降低了程序的检测次数,自然也就提升了分支结构的执行效率,避免空转,这在大批量数据检测中效果非常明显。

例如,对于一个论坛系统来说,普通会员的数量要远远大于版主和管理员的数量。

换句话说,大部分登录的用户都是普通会员,如果把普通会员的检测放在分支结构的前面,就会减少计算机检测的次数。

if优化目标:

最小化找到正确分支之前所判断条件体的数量。

if优化方法:

将最常见的条件体放在首位。

例如:

1.if(value < 5) { 

2.    //do something 

3.} else if(value > 5 && value < 10) { 

4.    //do something 

5.} else { 

6.    //do something 

7.} 

这段代码只有在value值经常小于5时才是最优的。

如果value经常大于或等于10,那么在进入正确分支之前,必须两次运算条件体,导致表达式的平均运行时间增加。

if中的条件体应当总是按照从最大概率到最小概率的顺序排列,以保证理论运行速度最快。

另外一种减少条件判断数量的方法:

将if编写成一系列嵌套结构。

使用一个单独的一长串的if结构通常导致运行缓慢,因为每个条件体都要被计算,例如:

1.if(value == 0) { 

2.    return result0; 

3.} else if(value == 1) { 

4.    return result1; 

5.} else if(value == 2) { 

6.    return result2; 

7.} else if(value == 3) { 

8.    return result3; 

9.} else if(value == 4) { 

10.    return result4; 

11.} else if(value == 5) { 

12.    return result5; 

13.} else if(value == 6) { 

14.    return result6; 

15.} else if(value == 7) { 

16.    return result7; 

17.} else if(value == 8) { 

18.    return result8; 

19.} else if(value == 9) { 

20.    return result9; 

21.} else { 

22.    return result10; 

23.} 

在这个if结构中,所计算的条件体的最大数目是10。

如果假设value的值在0~10之间均匀分布,那么会增加平均运行时间。

为了减少条件判断的数量,可重写为一系列嵌套结构,例如:

1.if(value < 6) { 

2.    if(value < 3) { 

3.        if(value == 0) { 

4.            return result0; 

5.        } else if(value == 1) { 

6.            return result1; 

7.        } else { 

8.            return result2; 

9.        } 

10.    } else { 

11.        if(value == 3) { 

12.            return result3; 

13.        } else if(value == 4) { 

14.            return result4; 

15.        } else { 

16.            return result5; 

17.        } 

18.    } 

19.} else { 

20.    if(value < 8) { 

21.        if(value == 6) { 

22.            return result6; 

23.        } else { 

24.            return result7; 

25.        } 

26.    } else { 

27.        if(value == 8) { 

28.            return result8; 

29.        } else if(value == 9) { 

30.            return result9; 

31.        } else { 

32.            return result10; 

33.        } 

34.    } 

35.} 

建议24:

优化if逻辑

(2)

重写if结构后,每次抵达正确分支时最多通过4个条件判断。

新的if结构使用二分搜索法将值域分成了一系列区间,然后逐步缩小范围。

当数值范围分布在0~10时,此代码的平均运行时间大约是前面代码的一半。

此方法适用于需要测试大量数值的情况,而相对离散值来说switch更合适。

当然,在性能影响不是很大的情况下,遵循条件检测的自然顺序会更容易阅读。

例如,对于检测周一到周五值日任务安排的分支结构来说,虽然周五的任务比较重要,但是这类任务有着明显的顺序,安排顺序结构还是遵循它的自然逻辑比较好。

如果打乱条件的顺序,把周五的任务安排在前面,对于整个分支结构的执行性能没有太大的帮助,并且不方便阅读代码。

考虑到这一点,按自然顺序来安排结构会更富可读性。

应注意分支之间的顺序优化,当然在同一个条件表达式内部也应该考虑逻辑顺序问题。

在执行逻辑“与”或逻辑“或”运算时,有可能会省略右侧表达式的计算,如果希望不管右侧表达式是否成立都进行计算,就应该考虑逻辑顺序问题。

例如,有两个条件a和b,其中条件a多为true,b就是一个必须执行的表达式,那么下面的逻辑顺序设计就欠妥当:

1.if(a && b){ 

2.} 

如果条件a为false,则JavaScript会忽略表达式b的计算。

如果b表达式影响到后面的运算,那么不执行表达式b自然会对后面的逻辑产生影响,这时可以采用下面的逻辑结构,在if结构前先执行表达式b,这样即使条件a的返回值为false,也能够保证表达式b被计算。

1.var c = b; 

2.if(a && b){ 

3.} 

建议25:

恰当选用if和switch

switch结构中存在很多限制,存在这些限制的主要目的是提高多重分支结构的执行效率。

因此,如果能够使用switch结构,就不要选择if结构。

无论是使用if结构,还是使用switch结构,应该确保下面3个目标的基本实现:

准确表现事物内在的、固有的逻辑关系。

不能为了结构而破坏事物的逻辑关系。

优化逻辑的执行效率。

执行效率是程序设计的重要目标,不能为了省事而随意耗费资源。

简化代码的结构层次,使代码更方便阅读。

相对来说,下面几种情况更适合使用switch结构:

枚举表达式的值。

这种枚举是可以期望的、平行逻辑关系的。

表达式的值具有离散性,不具有线性的非连续的区间值。

表达式的值是固定的,不是动态变化的。

表达式的值是有限的,而不是无限的,一般情况下表达式应该比较少。

表达式的值一般为整数、字符串等类型的数据。

而if结构则更适合下面的一些情况:

具有复杂的逻辑关系。

表达式的值具有线性特征,如对连续的区间值进行判断。

表达式的值是动态的。

测试任意类型的数据。

例如,针对学生分数进行不同的判断,如果分数小于60,则评定为不及格;如果分数在60~75(不包含75)之间,则评定为合格;如果分数在75~85(不包含85)之间,则评定为良好;如果分数在85~100之间,则评定为优秀。

针对这种情况,表达式的值是连续的线性判断,显然使用if结构会更合适一些。

1.if(score < 60){ 

2.    alert("不及格"); 

3.} 

4.else if(60 <= score < 75){ 

5.    alert("合格"); 

6.} 

7.else if(75 <= score < 85){ 

8.    alert("良好"); 

9.} 

10.else if(85 <= score <= 100){ 

11.    alert("优秀"); 

12.} 

如果使用switch结构,则需要枚举100种可能,如果分数值还包括小数,情况就更加复杂了,此时使用switch结构就不是明智之举。

但是,对于有限制的枚举数据,比如性别,使用switch结构会更高效,例如:

1.switch(sex){ 

2.    case "女":

 

3.        alert("女士"); 

4.        break; 

5.    case "男":

 

6.        alert("先生"); 

7.        break; 

8.    default:

 

9.        alert("请选择性别"); 

10.} 

建议26:

小心if嵌套的思维陷阱

人的思维是非常复杂的,这在一定程度上会增加if结构嵌套的复杂性。

假设有4个条件,只有当这些条件全部成立时,才允许执行某件事情。

遵循人的一般思维习惯,在检测这些条件时,常常会沿用下面这种结构嵌套:

1.if(a){ 

2.    if(b){ 

3.        if(c){ 

4.            if(d){ 

5.                alert("所有条件都成立!

"); 

6.            } 

7.         

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2