从数据结构的角度分析 for each in 比 for in 快的多


Posted in Javascript onJuly 07, 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里直接把每个values作为节点,通过链表关联起来维护。每当有值添加或删除,就更新其链接关系。
当for each...in遍历时,只需从第一个节点往后迭代即可,无需任何Hash计算。

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

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

Javascript 相关文章推荐
编辑浪子版表单验证类
May 12 Javascript
jquery+ashx无刷新GridView数据显示插件(实现分页、排序、过滤功能)
Apr 25 Javascript
input 和 textarea 输入框最大文字限制的jquery插件
Oct 27 Javascript
js实现下拉框选择要显示图片的方法
Feb 16 Javascript
AngularJS自动表单验证
Feb 01 Javascript
JS查找字符串中出现次数最多的字符
Sep 05 Javascript
原生js实现手风琴功能(支持横纵向调用)
Jan 13 Javascript
详解在Angularjs中ui-sref和$state.go如何传递参数
Apr 24 Javascript
vue 之 css module的使用方法
Dec 04 Javascript
js神秘的电报密码 哈弗曼编码实现
Sep 10 Javascript
js实现数字跳动到指定数字
Aug 25 Javascript
详解JavaScript的this指向和绑定
Sep 08 Javascript
JavaScript 上万关键字瞬间匹配实现代码
Jul 07 #Javascript
20行代码实现的一个CSS覆盖率测试脚本
Jul 07 #Javascript
在JavaScript里嵌入大量字符串常量的实现方法
Jul 07 #Javascript
JQuery表格内容过滤的实现方法
Jul 05 #Javascript
JS动态创建Table,Tr,Td并赋值的具体实现
Jul 05 #Javascript
Javascript实现动态菜单添加的实例代码
Jul 05 #Javascript
javascript实现跳转菜单的具体方法
Jul 05 #Javascript
You might like
制作美丽的拉花
2021/03/03 冲泡冲煮
生成静态页面的PHP类
2006/07/15 PHP
php实现mysql数据库操作类分享
2014/02/14 PHP
PHP中绘制图像的一些函数总结
2014/11/19 PHP
微信公众号支付之坑:调用支付jsapi缺少参数 timeStamp等错误解决方法
2016/01/12 PHP
JavaScript中的对象化编程
2008/01/16 Javascript
Javascript:为input设置readOnly属性(示例讲解)
2013/12/25 Javascript
jquery的ajax简单结构示例代码
2014/02/17 Javascript
JavaScript使用HTML5的window.postMessage实现跨域通信例子
2014/04/11 Javascript
javascript框架设计读书笔记之模块加载系统
2014/12/02 Javascript
《JavaScript DOM 编程艺术》读书笔记之DOM基础
2015/01/09 Javascript
jQuery实现页面评论栏中访客信息自动填写功能的方法
2016/05/23 Javascript
基于JS快速实现导航下拉菜单动画效果附源码下载
2016/10/27 Javascript
javascript replace()第二个参数为函数时的参数用法
2016/12/26 Javascript
jQuery基本选择器和层次选择器学习使用
2017/02/27 Javascript
详解vue+vueRouter+webpack的简单实例
2017/06/17 Javascript
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
weui上传多图片,压缩,base64编码的示例代码
2020/06/22 Javascript
ant design 日期格式化的实现
2020/10/27 Javascript
Python解析树及树的遍历
2016/02/03 Python
在pandas中一次性删除dataframe的多个列方法
2018/04/10 Python
python实现校园网自动登录的示例讲解
2018/04/22 Python
tensorflow实现简单逻辑回归
2018/09/07 Python
对pycharm 修改程序运行所需内存详解
2018/12/03 Python
win10系统Anaconda和Pycharm的Tensorflow2.0之CPU和GPU版本安装教程
2019/12/03 Python
Python要求O(n)复杂度求无序列表中第K的大元素实例
2020/04/02 Python
记一次Django响应超慢的解决过程
2020/09/17 Python
HOTEL INFO英国:搜索全球酒店
2019/08/08 全球购物
学习2014年全国两会心得体会
2014/03/12 职场文书
学校节能减排倡议书
2014/05/16 职场文书
公安机关党的群众路线教育实践活动剖析材料
2014/10/10 职场文书
2014年学校教学工作总结
2014/12/06 职场文书
财务工作个人总结
2015/02/27 职场文书
关于做家务的心得体会
2016/01/23 职场文书
MYSQL主从数据库同步备份配置的方法
2021/05/26 MySQL
postgresql无序uuid性能测试及对数据库的影响
2021/06/11 PostgreSQL