从数据结构的角度分析 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 相关文章推荐
js 页面传参数时 参数值含特殊字符的问题
Dec 13 Javascript
eval与window.eval的差别分析
Mar 17 Javascript
一个关于jqGrid使用的小例子(行按钮)
Nov 04 Javascript
jQuery之选择组件的深入解析
Jun 19 Javascript
JS分页效果示例
Oct 11 Javascript
jQuery实现列表自动滚动循环滚动展示新闻
Aug 22 Javascript
jQuery实现的漂亮表单效果代码
Aug 18 Javascript
jQuery Form 表单提交插件之formSerialize,fieldSerialize,fieldValue,resetForm,clearForm,clearFields的应用
Jan 23 Javascript
js实现多张图片延迟加载效果
Jul 17 Javascript
微信小程序商品详情页规格属性选择示例代码
Oct 30 Javascript
深入浅析Vue 中 ref 的使用
Apr 29 Javascript
layer提示框添加多个按钮选择的实例
Sep 12 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
PHP 函数语法介绍一
2009/06/14 PHP
php数组函数序列之next() - 移动数组内部指针到下一个元素的位置,并返回该元素值
2011/10/31 PHP
Ajax实时验证用户名/邮箱等是否已经存在的代码打包
2011/12/01 PHP
为PHP安装imagick时出现Cannot locate header file MagickWand.h错误的解决方法
2014/11/03 PHP
Yii使用ajax验证显示错误messagebox的解决方法
2014/12/03 PHP
PHP扩展迁移为PHP7扩展兼容性问题记录
2016/02/15 PHP
php获取一定范围内取N个不重复的随机数
2016/05/28 PHP
利用php抓取蜘蛛爬虫痕迹的示例代码
2016/09/30 PHP
php将服务端的文件读出来显示在web页面实例
2016/10/31 PHP
Yii框架分页实现方法详解
2017/05/20 PHP
一段非常简单的让图片自动切换js代码
2006/11/10 Javascript
js url传值中文乱码之解决之道
2009/11/20 Javascript
js导出table数据到excel即导出为EXCEL文档的方法
2013/10/10 Javascript
javascript中不等于的代码是什么怎么写
2013/12/29 Javascript
jQuery过滤选择器详解
2015/01/13 Javascript
jquery实现相册一下滑动两次的方法
2015/02/09 Javascript
JavaScript使用addEventListener添加事件监听用法实例
2015/06/01 Javascript
8 行 Node.js 代码实现代理服务器
2016/12/05 Javascript
javascript解析ajax返回的xml和json格式数据实例详解
2017/01/05 Javascript
vue中$nextTick的用法讲解
2019/01/17 Javascript
javascript设计模式 ? 访问者模式原理与用法实例分析
2020/04/26 Javascript
[52:20]VP vs VG Supermajor小组赛 B组胜者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
Python批量修改文件后缀的方法
2014/01/26 Python
Python使用plotly绘制数据图表的方法
2017/07/18 Python
python利用sklearn包编写决策树源代码
2017/12/21 Python
python实现基于信息增益的决策树归纳
2018/12/18 Python
对python 自定义协议的方法详解
2019/02/13 Python
css3类选择器之结合元素选择器和多类选择器用法
2017/03/09 HTML / CSS
自荐信格式写作方法有哪些呢
2013/11/20 职场文书
电视购物广告词
2014/03/19 职场文书
2014年社区民政工作总结
2014/12/02 职场文书
保护环境建议书作文300字
2015/09/14 职场文书
家访教师心得体会
2016/01/23 职场文书
区域销售大会开幕词
2016/03/04 职场文书
Python爬虫之爬取某文库文档数据
2021/04/21 Python
Java多条件判断场景中规则执行器的设计
2021/06/26 Java/Android