通过循环优化 JavaScript 程序

前言

对于提高 JavaScript 程序的性能这个问题,最简单同时也是很容易被忽视的方法就是学习如何正确编写高性能循环语句。本文将会帮你解决这个问题。

我们将看到 JavaScript 中主要的循环类型,以及如何针对它们进行高效编码。

现在开始!

循环性能

谈到循环性能,争论的焦点始终会集中到关于应该使用哪种循环,哪个是速度最快、性能最好的?事实上,在 JavaScript 提供的四种循环类型中,只有一种比其他循环慢得多 ——  for-in 循环。 对循环类型的选择应基于你的需求而不是性能问题。

有两个主要因素有助于改善循环性能 —— 每次迭代完成的工作和迭代次数。

在下面的内容中,我们将会看到通过对这两点的优化,可以对循环的整体性能产生积极的影响。

For 循环

在 ECMA-262(定义JavaScript的基本语法和行为的规范)第三版中,定义了四种循环类型。第一个是标准的 for 循环,它与其他类 C 语言的语法相同:

for (var i = 0; i < 10; i++){
//循环体
}

这可能是最常用的 JavaScript 循环结构。要了解应该怎样对其进行优化,需要先进行一些分析。

解析

for 循环由四部分组成:初始化,预测试条件,循环体和后执行。它的工作方式如下:首先,执行初始化代码(var i = 0;)。然后是预测试条件(i <10;)。如果预测试条件的计算结果为 true,则执行循环体。之后运行后执行代码(i ++)。

优化

要优化循环中的工作量,第一步是最小化对象成员和数组项查找的数量。
还可以通过反转顺序来提高循环的性能。在 JavaScript 中,反转循环对循环的性能提升不大,除非你消除了额外的操作。

// 原始循环
for (var i = 0; i < items.length; i++){
process(items[i]);
}
// 最小化属性查找
for (var i = 0, len = items.length; i < len; i++){
process(items[i]);
}
// 最小化属性查找并反序
for (var i = items.length; i--; ){
process(items[i]);
}

While 循环

第二种是 while 循环。下面是一个简单的预测试循环,由预测试条件和循环体组成。

var i = 0;
while(i < 10){
//循环体
i++;
}

解析

如果预测试条件的计算结果为 true,则执行循环体。如果不是 —— 它就会被跳过。每个 while 循环都可以用 for 替换,反之亦然。

优化

// 原始循环
var j = 0;
while (j < items.length){
process(items[j++]);
}
// 最小化属性查找
var j = 0,
count = items.length;
while (j < count){
process(items[j++]);
}
// 最小化属性查找和反序
var j = items.length;
while (j--){
process(items[j]);
}

Do-While 循环

do-while 是第三种循环,它是 JavaScript 中唯一的后测试循环。由循环体和后测试条件组成:

var i = 0;
do {
//循环体
} while (i++ < 10);

解析

在这种类型的循环中,循环体总是至少执行一次。然后评估测试后的条件,如果它是true,则执行另一个循环周期。

优化

// 原始循环
var k = 0;
do {
process(items[k++]);
} while (k < items.length);
// 最小化属性查找
var k = 0,
num = items.length;
do {
process(items[k++]);
} while (k < num);
// 最小化属性查找和反序
var k = items.length - 1;
do {
process(items[k]);
} while (k--);

For-In 循环

最后一种是 for-in 循环。它有一个非常特殊的用途 —— 枚举 JavaScript 对象的命名属性。 它的语法如下:

for (var prop in object){
//loop body
}

解析

它的名称与 for 循环类似。但是工作方式完全不同。而这种差异使它比另外三种循环慢得多,后者具有相同的性能特征,所以争论哪个循环最快是没有用的。

每次循环执行时,变量 prop 会得到 object 的一个属性。它将会不断执行,直到返回所有属性为止。这些是对象自身的以及通过其原型链继承的属性。

注意事项

永远不要用“ for-in ”来迭代数组成员。

这种循环的每次迭代都会在实例或原型上进行属性查找,这使得 for-in 循环比其它循环要慢得多。对于相同次数的迭代,可能会比其它循环慢七倍。

结论

for , while 和 do-while 循环都有类似的性能特征,因此没有哪种类型比其他的更快或更慢。

避免使用 for-in 循环,除非你需要对大量未知对象属性进行迭代。

提高循环性能的最佳方法是减少每次迭代完成的工作量并减少循环迭代次数。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 利用Node.js如何实现文件循环覆写

    前言 这次编写Node.js项目的时候用到了日志模块,其中碰到了一个小问题. 这是一个定时执行可配置自动化任务的项目,所以输出信息会不断增加,也就意味着日志文件会随时间不断增大.如果对日志文件大小不加以控制,那么服务器的磁盘迟早会被撑满.所以限制文件大小是有必要的. 最理想的控制方式就是当文件大小超过限制时,清除最先记录的数据.类似一个FIFO的队列. # 删除前面的数据 - 1 xxx ...... 100 abc # 文件末尾追加数据 + 101 xxxx log4js的file rolli

  • 详解JS浏览器事件循环机制

    先来明白些概念性内容. 进程.线程 进程是系统分配的独立资源,是 CPU 资源分配的基本单位,进程是由一个或者多个线程组成的. 线程是进程的执行流,是CPU调度和分派的基本单位,同个进程之中的多个线程之间是共享该进程的资源的. 浏览器内核 浏览器是多进程的,浏览器每一个 tab 标签都代表一个独立的进程(也不一定,因为多个空白 tab 标签会合并成一个进程),浏览器内核(浏览器渲染进程)属于浏览器多进程中的一种. 浏览器内核有多种线程在工作. GUI 渲染线程: 负责渲染页面,解析 HTML,C

  • 浅谈JS闭包中的循环绑定处理程序

    前几天工作中写前端js代码时,遇到了遍历元素给它添加单击事件.就是这个问题让我整整调了一个下午.最后还是下班回家,上网查资料才知道怎么解决的. (PS:之前也在<jQuery基础教程>第四版中看过讲循环绑定处理程序的内容,当时估计也没怎么用心看,所以没记起来.) 大神要是知道这类情况,可以关掉窗口,写这些主要是给像我一样的小白看的.谢谢! 先贴上错误的例子让大家看看.(例子里面用到jQuery,请导入jQuery库) 复制代码 代码如下: <!DOCTYPE html PUBLIC &q

  • JS实现的图片选择顺序切换和循环切换功能示例【测试可用】

    本文实例讲述了JS实现的图片选择顺序切换和循环切换功能.分享给大家供大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> &l

  • 如何在JavaScript中优雅的提取循环内数据详解

    前言 在本文中,我们将介绍两种提取循环内数据的方法:内部迭代和外部迭代.分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 循环 举个例子,假设有一个函数 logFiles(): const fs = require('fs'); const path = require('path'); function logFiles(dir) { for (const fileName of fs.readdirSync(dir)) { // (A) const filePath = pat

  • 前端js中的事件循环eventloop机制详解

    前言 我们知道 js 是单线程执行的,那么异步的代码 js 是怎么处理的呢?例如下面的代码是如何进行输出的: console.log(1); setTimeout(function() { console.log(2); }, 0); new Promise(function(resolve) { console.log(3); resolve(Date.now()); }).then(function() { console.log(4); }); console.log(5); setTim

  • 通过循环优化 JavaScript 程序

    前言 对于提高 JavaScript 程序的性能这个问题,最简单同时也是很容易被忽视的方法就是学习如何正确编写高性能循环语句.本文将会帮你解决这个问题. 我们将看到 JavaScript 中主要的循环类型,以及如何针对它们进行高效编码. 现在开始! 循环性能 谈到循环性能,争论的焦点始终会集中到关于应该使用哪种循环,哪个是速度最快.性能最好的?事实上,在 JavaScript 提供的四种循环类型中,只有一种比其他循环慢得多 --  for-in 循环. 对循环类型的选择应基于你的需求而不是性能问

  • 使用Function.apply()的参数数组化来提高 JavaScript程序性能的技巧

    我们再来聊聊Function.apply() 在提升程序性能方面的技巧. 我们先从 Math.max() 函数说起, Math.max后面可以接任意个参数,最后返回所有参数中的最大值. 比如 alert(Math.max(5,8)) //8 alert(Math.max(5,7,9,3,1,6)) //9 但是在很多情况下,我们需要找出数组中最大的元素. var arr=[5,7,9,1] alert(Math.max(arr)) // 这样却是不行的.一定要这样写 function getMa

  • 优化 JavaScript 代码的方法小结

    优化 JavaScript 代码 作者: Gregory Baker, GMail 软件工程师 和 Erik Arvidsson, Google Chrome 软件工程师 需要的经验: JavaScript 相关工作知识 客户端脚本能让你的应用更加地动态和活跃, 但是浏览器对代码的解析可能造成效率问题, 而这种性能差异在客户端之间也不尽相同. 这里我们讨论和给出一些优化你的 JavaScript 代码的提示和最佳实践. 使用字符串 字符串连接操作会对 Internet Explorer 6 和

  • JavaScript 程序编码规范

    软件的长期价值直接源于其编码质量.在它的整个生命周期里,一个程序可能会被许多人阅读或修改.如果一个程序可以清晰的展现出它的结构和特征,那就能减少在以后对其进行修改时出错的可能性.编程规范可以帮助程序员们增加程序的健壮性. 所有的JavaScript代码都是暴露给公众的.所以我们更应该保证其质量.保持整洁很重要. JavaScript文件 JavaScript程序应独立保存在后缀名为.js的文件中. JavaScript代码不应该被包含在HTML文件中,除非这是段特定只属于此部分的代码.在HTML

  • JavaScript 程序错误Cannot use 'in' operator to search的解决方法

    今天编程时,JavaScript 程序报了这样的错误:Cannot use 'in' operator to search for...,具体错误信息如下: 坦白说,这样的错误最难调试.因为它并不指向你所写的具体代码,而是泛泛指向了 lib.js 文件(该文件通常是第三方的打包压缩库),你几乎无法依据错误类型与错误指向来定位到实际编程中的错误位置. 怎么办? 这个时候,只有发挥"死磕"精神了! 死磕步骤: 依据故障页面以及错误信息,定位到出错的文件,这一点应该不难: 在出错的页面中,依

  • 优化javascript的执行效率一些方法总结

    1.在低版本浏览器中(如IE6,IE7等)串联字符串时使用数组的join方法就比使用+号来连接高效很多(如['aaa','bbb','ccc'].join()比'aaa'+'bbb'+'ccc'高效): 2.Array: pop比shift高效,push比unshift高效.这对于设计二叉堆结构比较重要,将最大或者最小的元素放在数组末尾最好. 3.数字取整最好用移位操作: 1.1 >> 0; 4.使用直接量创建Array和Object: var a = []; var o = {}; 5.对象

  • Go 内联优化让程序员爱不释手

    目录 前言: 什么是内联? 为什么内联很重要? 函数调用的开销 基本知识 Go 中的开销 Go 里的优化 改善优化的机会 进行内联优化 不允许内联 允许内联 这些改进从何而来? 内联的限制 总结 前言: 这是一篇介绍 Go 编译器如何实现内联的文章,以及这种优化将如何影响你的 Go 代码. 什么是内联? 内联是将较小的函数合并到它们各自的调用者中的行为.其在不同的计算历史时期的做法不一样,如下: 早期:这种优化通常是由手工完成的. 现在:内联是在编译过程中自动进行的一类基本优化之一. 为什么内联

  • JS前端千万级弹幕数据循环优化示例

    目录 引言 1.如何删除数组中的元素 2.10000,000条消息如何优化? 场景 常规思路: 产生的问题 优化策略 代码实现 效果展示 小结 游标法代替splice 二分查找 完结 引言 最近做了直播相关的业务,然后对于大数据相关的优化做了一下复盘. 为了了解我是怎么做这个优化的,我们先从如何按照特定的条件删除一个数组说起. 1.如何删除数组中的元素 场景:有一个数组,需要删除满足条件的数组. 示例: const arr = [1,2,3,4,5,6,7,8] 删除小于5的元素,删除后的元素为

  • 多阶段构建优化Go 程序Docker镜像

    目录 引言 构建 Docker 镜像 是否可以再减小 Docker 镜像的大小? 引言 多阶段构建方式,是在 Dockerfile 中使用多个 FROM 指令,每个 FORM 指令都是一个新的构建阶段,并且可以方便地复制之前阶段的构件.让我们来看一个简单的 Go 程序.代码如下. 点击此处您可以获取代码. 构建 Docker 镜像 让我们来为它构建 Docker 镜像,Dockerfile 文件内容如下. FROM golang:1.19-alpine WORKDIR /build COPY g

  • JavaScript 程序循环结构详解

    目录 选择结构 循环结构 while do - while for 循环 for - in - for -of- 小结 终止循环 break continue 二层循环 总结 选择结构 单分支的if结构 if(条件){ 条件满足后执行的代码 } 如果大括号中只有一条语句,此时可以省略大括号,但是强烈不建议这样写 if(条件) console.log('点点点') 二分支if结构语句 if (条件){ 条件满足后执行的代码 } else{ 条件不满足后执行的代码 } 多分支if结构语句 if(条件

随机推荐