通过循环优化 JavaScript 程序


Posted in Javascript onJune 24, 2019

前言

对于提高 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 循环,除非你需要对大量未知对象属性进行迭代。

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

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

Javascript 相关文章推荐
自动生成文章摘要的代码[JavaScript 版本]
Mar 20 Javascript
javascript加号&quot;+&quot;的二义性说明
Mar 04 Javascript
JS 获取浏览器和屏幕宽高等信息的实现思路及代码
Jul 31 Javascript
javaScript面向对象继承方法经典实现
Aug 20 Javascript
js实现C#的StringBuilder效果完整实例
Dec 22 Javascript
EasyUI加载完Html内容样式渲染完成后显示
Jul 25 Javascript
AngularJS动态生成div的ID源码解析
Aug 29 Javascript
JavaScript使用Ajax上传文件的示例代码
Aug 10 Javascript
Vue2.0学习系列之项目上线的方法步骤(图文)
Sep 25 Javascript
JS前端知识点offset,scroll,client,冒泡,事件对象的应用整理总结
Jun 27 Javascript
vue悬浮可拖拽悬浮按钮的实例代码
Aug 20 Javascript
如何利用 JS 脚本实现网页全自动秒杀抢购功能
Oct 12 Javascript
在React中写一个Animation组件为组件进入和离开加上动画/过度效果
Jun 24 #Javascript
node中实现删除目录的几种方法
Jun 24 #Javascript
什么时候不能在 Node.js 中使用 Lock Files
Jun 24 #Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
Jun 24 #Javascript
浅谈一个webpack构建速度优化误区
Jun 24 #Javascript
vue项目中运用webpack动态配置打包多种环境域名的方法
Jun 24 #Javascript
Vue.js+cube-ui(Scroll组件)实现类似头条效果的横向滚动导航条
Jun 24 #Javascript
You might like
PHP.vs.JAVA
2016/04/29 PHP
php htmlentities()函数的定义和用法
2016/05/13 PHP
PHP请求远程地址设置超时时间的解决方法
2016/10/29 PHP
JavaScript实现随机替换图片的方法
2015/04/16 Javascript
javascript实现验证IP地址等相关信息代码
2015/05/10 Javascript
js实现一个链接打开两个链接地址的方法
2015/05/12 Javascript
Javascript中的getUTCDay()方法使用详解
2015/06/10 Javascript
JS点击某个图标或按钮弹出文件选择框的实现代码
2016/09/27 Javascript
微信小程序 开发经验整理
2017/02/15 Javascript
axios基本入门用法教程
2017/03/25 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
2017/11/10 Javascript
浅谈Vue Element中Select下拉框选取值的问题
2018/03/01 Javascript
vue2单元测试环境搭建
2018/05/24 Javascript
vue中js判断长时间不操作界面自动退出登录(推荐)
2020/01/22 Javascript
vue+echarts实现动态折线图的方法与注意
2020/09/01 Javascript
python使用Matplotlib画饼图
2018/09/25 Python
检测python爬虫时是否代理ip伪装成功的方法
2019/07/12 Python
Python从入门到精通之环境搭建教程图解
2019/09/26 Python
用python3读取python2的pickle数据方式
2019/12/25 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
2020/06/11 Python
python 如何上传包到pypi
2020/12/24 Python
open_basedir restriction in effect. 原因与解决方法
2021/03/14 PHP
深入CSS3 动画效果的总结详解
2013/05/09 HTML / CSS
茵宝(Umbro)英国官方商店:英国足球服装生产商
2016/12/29 全球购物
Farah官方网站:男士服装及配件
2019/11/01 全球购物
全球精选男装和家居用品:Article
2020/04/13 全球购物
工程师岗位职责
2013/11/08 职场文书
个人安全生产承诺书
2014/05/22 职场文书
政协工作总结2015
2015/05/20 职场文书
结婚典礼主持词
2015/06/29 职场文书
2016年党课培训学习心得体会
2016/01/07 职场文书
golang interface判断为空nil的实现代码
2021/04/24 Golang
面试必问:圣杯布局和双飞翼布局的区别
2021/05/13 HTML / CSS
pytorch DataLoader的num_workers参数与设置大小详解
2021/05/28 Python
java后台调用接口及处理跨域问题的解决
2022/03/24 Java/Android
Python实现科学占卜 让视频自动打码
2022/04/09 Python