JavaScript 基础教程JavaScript 简介JavaScript 用法JavaScript 输出JavaScript 语法JavaScript 语句JavaScript 注释JavaScript 变量JavaScript 数据类型JavaScript 对象JavaScript 函数JavaScript 作用域JavaScript 事件JavaScript 字符串JavaScript 运算符JavaScript 比较和逻辑运算符JavaScript if...else 语句JavaScript switch 语句JavaScript for 循环JavaScript while 循环JavaScript break 和 continue 语句JavaScript typeof, null, undefinedJavaScript 类型转换JavaScript 正则表达式JavaScript 错误throw try catchJavaScript 调试JavaScript 变量提升JavaScript 严格模式 (use strict)JavaScript 使用误区JavaScript 表单JavaScript 表单验证JavaScript 验证 APIJavaScript 保留关键字JavaScript JSONjavascript :void(0) 含义JavaScript 代码规范JavaScript 函数定义JavaScript 函数参数JavaScript 函数调用JavaScript 闭包JavaScript HTML DOMJavaScript DOM- 改变 HTMLJavaScript DOM - 改变 CSSJavaScript HTML DOM 事件JavaScript DOM EventListenerJavaScript DOM 元素(节点)JavaScript 对象类型JavaScript Number 对象JavaScript 字符串(String)对象JavaScript Date 对象JavaScript Array 对象JavaScript Boolean 对象JavaScript Math 对象JavaScript RegExp 对象JavaScript window 对象JavaScript window.screen 对象JavaScript window.location 对象JavaScript window.history 对象JavaScript window.navigator 对象JavaScript 弹窗JavaScript 计时事件JavaScript CookieJS中的if和switch该如何选择?JS优化多分支结构JS中的while和for循环该如何选择?JS优化循环结构JS输出杨辉三角JS定义字符串(3种方式)JS获取字符串长度JS字符串拼接/连接(3种方式)JS字符串查找(6种方法)JS截取字符串JS字符串替换replace()JS字符串大写小写转换JS字符串比较大小JS字符串和数组之间的转换JS给字符串添加HTML标签JS去除字符串前后空格JS Unicode编码和解码JS Base64编码和解码JS在接收表单数据时过滤特殊字符JS自定义编码和解码方案

JS优化循环结构

循环时最耗费资源的操作,任意一点小小的损耗都会被成倍放大,从而影响到程序整体运行的效率。一下两个因素会影响到循环的性能。

每次迭代做什么
迭代的次数

通过减少这两者中一个或全部的执行时间,可以提高循环的整体性能。如果一次循环需要较长时间,那么多次循环将需要更长时间。

示例1

下面使用 3 类循环语句设计一个典型的数组遍历操作。

//方法1
for (var i = 0;i < items.length;i ++) {
process(items[i]);
}

//方法2
var j = 0;
while (j < items.length) {
process(items[j++]);
}

//方法3
var k = 0;
do {
process(items[k++]);
} while (k < items.length);


减少循环

对于任何循环来说,每次执行循环体都要发生一下操作。

在控制条件中读一次属性(items.length)。
在控制条件中执行一次比较(i < itesm.length)。
判断 i<items.length 表达式的值是不是 true(i < items.length == true)。
一次自加操作(i++)。
一次数组查找(items[i])。
一次函数调用(process(items[i]))。

在循环体内,代码运行速度很大程度上由 process() 对每个项目的操作决定,即便如此,减少每次迭代中操作的总数也可以大幅度提高循环的性能。
优化循环的第一步是减少对象成员和数组项查找的次数。在大多数浏览器上,这些操作比访问局部变量或直接量需要更长的时间。

示例2

在上面代码中,每次循环都查找 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);

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


倒序循环

还可以通过改变循环的顺序来提高循环性能。通常,数组元素的处理顺序与任务无关,可以从最后一个开始,直到处理完第一个元素。倒序循环是编程语言中常用的性能优化方法。

示例3

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

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 --);

在上面代码中使用了倒序循环,并在控制条件中使用了自减。每个控制条件只是简单地与 0 进行比较。控制条件与 true 值进行比较,任何非零数字自动强制转换为 true,而 0 等同于 false。
实际上,控制条件已经从两次比较减少到一次比较,大幅提高了循环速度。与原始版本相比,现在每次迭代中只进行以下操作。

在控制条件中进行一次比较(i == true)。
一次减法操作(i --)。
一次数组查询(items[i])。
一次函数调用(process(items[i]))。

每次迭代中减少两个操作,如果迭代次数成千上万的增长,那么性能将显著提升。


嵌套设计

循环结构常与分支结构混用在一起,但是如何嵌套就就非常讲究了。

示例4 

在一个循环体内,设计只有在特定条件下才执行循环体。

var a = true;
for (var b = 1;b < 10 ;b ++) { //循环结构
if (a == true) { //条件判断
console.log(b);
}
}

很明显,在这个循环中,if 语句会被反复执行。如果 if 的条件不受循环遍历影响,则不妨采用下面嵌套结构来设计。

if (a == true) {  //条件判断
for (var b = 1; b < 10; b ++ ) { //循环结构
console.log(b);
}
}

这样 if 语句只被循环一次,如果 if 条件不成立,则直接省略 for 语句的执行,从而使程序的执行效率大大提高。但是如果 if 条件表达式受循环结构的制约,就不能采用这种方式。


重复声明

在循环体内经常会存在不必要的重复声明。

示例5

下面示例设计在循环内声明数组。

for (var b = 0; b < 10; b ++) {  //循环
var a = new Array(1,2,3,4,5,6,7,8,9,10); //声明并初始化数组
console.log(a[b]);
}

如果把声明数组放在循环体外会更高效。

var a = new Array(1,2,3,4,5,6,7,8,9,10);  //声明并初始化数组
for (var b = 0; b < 10; b ++) { //循环
console.log(a[b]);
}


定义循环变量

对于 for 语句来说,当循环变量仅用于循环控制时,不妨在 for 内定义。

示例6

计算 100 之内数字的和。

var s = 0;  //声明变量
for (var i = 0; i <= 100; i ++) { //循环语句
s += i;
}
console.log(s);

显然下面的做法就不妥当,会增大系统开销。

var i = 0;  //声明变量
var s = 0; //声明变量
for (i = 0; i <= 100; i ++) { //循环语句
s += i;
}


链接: https://fly63.com/course/7_532