代码的组织结构和解决具体问题的思路是影响代码性能的主要因素。
1. 循环的类型
(1) for 循环
(2) while 循环
(3) do-while 循环
(4) for-in循环
2. 循环性能
在js的四种循环类型中,只有for-in循环比其他四种明显要慢。
原因:由于每次迭代操作会同时搜索实例或原型属性,for-in循环的每次迭代都会产生更多的开销,所以比其他循环类型要慢。
提高循环性能的方案:
(1) 减少迭代的工作量
原始代码:
for (var i = 0; i < items.length; i++){
process(items[i]);
}
var j = 0;
while( j < items.length ){
process(items[j++])
}
var k = 0;
do{
process(items[k++])
} while ( k < items.length )
重构:
//最小化属性查找
for ( var i = 0, len = items.length; i < len; i++){
process(items[i]);
}
var j = 0,
count = items.length;
while( j < count ){
process(items[j++])
}
var k = 0,
num = items.length;
do{
process(items[k++])
} while ( k < num );
如果循环中复杂度较高,可采用倒序循环:
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--);
(2) 减少迭代次数
减少迭代次数能获得更佳显著的性能提升。
3. 基于函数的迭代
4. 条件语句
条件表达式决定了js运行流的走向。
(1) 优化 if-else
确保最可能出现的条件放在首位。
(2) 查找表
对于switch语句,如果可选项太多,可以使用查找表的方法:
switch(value){
case 0:
return result0;
case 1:
return result1;
case 2:
return result2;
case 3:
return result3;
case 4:
return result4;
case 5:
return result5;
case 6:
return result6;
case 7:
return result7;
default:
return result10;
}
以上写法太繁琐,可以这样:
var results = [result1, result2, result3, result4, result5,
result6, result7, result10]
return results[value];
5 递归
递归函数的潜在问题是:
(1) 终止条件不明确或缺少终止条件会导致函数长时间运行,并使得用户界面处于假死状态。
(2) 可能会遇到浏览器的“调用栈大小限制”
6. 调用栈限制
js引擎支持的递归数量与js调用栈大小直接相关。只有ie例外,它的调用栈与系统空闲内存有关,而其他所有浏览器都有固定数量的调用栈限制。
当你使用了太多的递归,甚至超过最大调用栈容量时,浏览器会报以下出错信息:
IE:Stack overflow at line x
Firefox:Too much recursion
Safari:Maximum call stack size exceeded
Opera:Abort(control stack overflow)
Chrome:是唯一不显示调用栈溢出错误的浏览器。
7. 递归模式
(1) 直接递归模式:
function recurse(){
recurse();
}
recurse();
(2) 包含两个函数的“隐伏模式”
function first(){
second();
}
function second(){
first();
}
first();
8. 迭代
把递归算法改用迭代实现是避免栈溢出错误的方法之一