从数据结构分析看:用for each...in 比 for...in 要快些


Posted in Javascript onApril 17, 2013

之前听说火狐的JS引擎支持for each in的语法,例如下述的代码:

var arr = [10,20,30,40,50];
for each(var k in arr)
    console.log(k);

即可直接遍历出arr数组的内容。

由于只有FireFox才支持,所以几乎所有的JS代码都不用这一特征。

不过在ActionScript里天生就支持for each的语法,不论Array还是Vector,还是Dictionary,只要是可枚举的对象都可以for in和for each in。

之前并没有感觉有太大的差异,为了懒得敲一个each单词,一直用熟悉的for in来遍历。

不过今天仔细琢磨了会,从数据结构的角度分析了下,觉得for in和for each in效率上有着本质的区别,无论是JS还是AS。

原因很简单:Array不是真正意义上的数组!

何为真正意义的数组?当然就是传统语言里type[]定义的数据类型,所有元素都是连续保存的。

“Array”虽然也是数组的意思,但熟悉JS的都知道,它其实是个非线性的伪数组,下标可以是任意数字。写入arr[1000000]并非真正申请容纳一百万个元素的空间,而是把1000000转换成相应的哈希值,对应到很小一块储存空间里,从而节省了大量内存。

例如有如下数组:

var arr = [];
  arr[10] = 1000;
  arr[20] = 2000;
  arr[30] = 5000;
  arr[40] = 8000;
  arr[200] = 9000;

用for...in遍历Array,是个很累赘的过程:

从数据结构分析看:用for each...in 比 for...in 要快些

遍历时每次访问arr[k],都要进行一次Hash(k)计算,根据散列表的容量取模,最终在冲突链表里找到结果。

如果支持for each...in的语法,其内部的数据结构就决定了会快很多:

从数据结构分析看:用for each...in 比 for...in 要快些

Array里储存存了keys的列表,也把每个values值作为链表关联起来。每当有值添加或删除,就更新其链接关系。

当for each...in遍历时,只需从第一个节点往后迭代即可,无需任何Hash计算。

当然,对于AS3里Vector这样的线性数组来说,两者相差不大;同理,HTML5里支持二进制的数组ArrayBuffer也是如此。不过从理论上来看,即使arr是个连续的线性数组,for each in还是要快一点:

for...in遍历时,每次访问arr[k]都要进行下标越界检查;而for each in则根据内部链表,直接从底层反馈出迭代变量,节省了越界检查的过程。

Javascript 相关文章推荐
用jquery统计子菜单的条数示例代码
Oct 18 Javascript
jQuery中fadeOut()方法用法实例
Dec 24 Javascript
jQuery实现炫酷的鼠标轨迹特效
Feb 01 Javascript
jQuery之动画效果大全
Nov 09 Javascript
jQuery无刷新上传之uploadify简单代码
Jan 17 Javascript
jquery 仿锚点跳转到页面指定位置的实例
Feb 14 Javascript
Node.js服务器开启Gzip压缩教程
Aug 11 Javascript
JS实现自定义弹窗功能
Aug 08 Javascript
浅析Vue实例以及生命周期
Aug 14 Javascript
vue+elementUI实现表格关键字筛选高亮
Oct 26 Javascript
extjs图表绘制之条形图实现方法分析
Mar 06 Javascript
JavaScript数组类型Array相关的属性与方法详解
Sep 08 Javascript
关于eval 与new Function 到底该选哪个?
Apr 17 #Javascript
js实现在页面上弹出蒙板技巧简单实用
Apr 16 #Javascript
主页面中的两个iframe实现鼠标拖动改变其大小
Apr 16 #Javascript
拖动table标题实现改变td的大小(css+js代码)
Apr 16 #Javascript
获取offsetTop和offsetLeft值的js代码(兼容)
Apr 16 #Javascript
jquery表格内容筛选实现思路及代码
Apr 16 #Javascript
js实现图片轮换效果代码
Apr 16 #Javascript
You might like
MYSQL数据库初学者使用指南
2006/11/16 PHP
实现 win2003 下 mysql 数据库每天自动备份
2006/12/06 PHP
php图片上传存储源码并且可以预览
2011/08/26 PHP
PHP实现根据设备类型自动跳转相应页面的方法
2014/07/24 PHP
PHP实现指定字段的多维数组排序函数分享
2015/03/09 PHP
Jquery Validation插件防止重复提交表单的解决方法
2010/03/05 Javascript
XMLHTTP 乱码的解决方法(UTF8,GB2312 编码 解码)
2011/01/12 Javascript
iframe子父页面调用js函数示例
2013/11/07 Javascript
Jquery结合HTML5实现文件上传
2015/06/25 Javascript
jQuery实现简单的点赞效果
2020/05/29 Javascript
AngularJS控制器controller正确的通信的方法
2016/01/25 Javascript
jQuery设置Cookie及删除Cookie实例分析
2016/04/15 Javascript
ReactNative Image组件使用详解
2017/08/07 Javascript
jQuery选择器特殊字符与属性空格问题
2017/08/14 jQuery
VUE2 前端实现 静态二级省市联动选择select的示例
2018/02/09 Javascript
在iFrame子页面里实现模态框的方法
2018/08/17 Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
2020/06/05 Javascript
vue+iview实现分页及查询功能
2020/11/17 Vue.js
Python实现曲线点抽稀算法的示例
2017/10/12 Python
如何使用Python自动控制windows桌面
2019/07/11 Python
python根据多个文件名批量查找文件
2019/08/13 Python
Anaconda详细安装步骤图文教程
2020/11/12 Python
html5中的input新属性range使用记录
2014/09/05 HTML / CSS
英国定做窗帘和纺织品面料一站式商店:Dekoria
2018/08/29 全球购物
vue 中 get / delete 传递数组参数方法
2021/03/23 Vue.js
小学教师的自我评价范例
2013/10/31 职场文书
乡镇干部先进事迹材料
2014/02/03 职场文书
幸福家庭事迹材料
2014/02/03 职场文书
房屋出售授权委托书
2014/10/12 职场文书
淘宝好评语句大全
2014/12/31 职场文书
2015年财务工作总结范文
2015/03/31 职场文书
民事撤诉申请书范本
2015/05/18 职场文书
《夜莺的歌声》教学反思
2016/02/22 职场文书
Java面试题冲刺第十五天--设计模式
2021/08/07 面试题
7个关于Python的经典基础案例
2021/11/07 Python
实现AJAX异步调用和局部刷新的基本步骤
2022/03/17 Javascript