从数据结构的角度分析 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 相关文章推荐
一个对于Array的简单扩展
Oct 03 Javascript
Javascript图像处理—亮度对比度应用案例
Jan 03 Javascript
js如何设置在iframe框架中指定div不显示
Dec 04 Javascript
javascript数字时钟示例分享
Apr 23 Javascript
jQuery实现输入框下拉列表树插件特效代码分享
Aug 27 Javascript
jQuery+JSON实现AJAX二级联动实例分析
Dec 18 Javascript
基于javascript实现简单计算器功能
Jan 03 Javascript
基于BootStrap与jQuery.validate实现表单提交校验功能
Dec 22 Javascript
详解Angular Reactive Form 表单验证
Jul 06 Javascript
react native基于FlatList下拉刷新上拉加载实现代码示例
Sep 30 Javascript
vue-cli3 项目从搭建优化到docker部署的方法
Jan 28 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
Jun 16 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
smarty静态实验表明,网络上是错的~呵呵
2006/11/25 PHP
PHP 多维数组排序(usort,uasort)
2010/06/30 PHP
php实现文件下载功能的几个代码分享
2014/05/10 PHP
php组合排序简单实现方法
2016/10/15 PHP
php str_getcsv把字符串解析为数组的实现方法
2017/04/05 PHP
jQueryPad 实用的jQuery测试工具(支持IE,chrome,FF)
2010/05/22 Javascript
关于jQuery参考实例2.0 用jQuery选择元素
2013/04/07 Javascript
用jQuery toggleClass 实现鼠标移上变色
2014/05/14 Javascript
jQuery实现购物车计算价格功能的方法
2015/03/25 Javascript
使用canvas实现仿新浪微博头像截取上传功能
2015/09/02 Javascript
Bootstrap每天必学之缩略图与警示窗
2015/11/29 Javascript
深入理解JavaScript单体内置对象
2016/06/06 Javascript
点击按钮出现60秒倒计时的简单js代码(推荐)
2016/06/07 Javascript
使用Javascript监控前端相关数据的代码
2016/10/27 Javascript
select下拉框插件jquery.editable-select详解
2017/01/22 Javascript
jQuery阻止移动端遮罩层后页面滚动
2017/03/15 Javascript
JavaScript通过filereader接口读取文件
2017/05/10 Javascript
jQuery Validate表单验证插件实现代码
2017/06/08 jQuery
用npm安装vue和vue-cli,并使用webpack创建项目的方法
2018/09/28 Javascript
D3.js(v3)+react 实现带坐标与比例尺的散点图 (V3版本)
2019/05/09 Javascript
微信小程序判断页面是否从其他页面返回的实例代码
2019/07/03 Javascript
vue props 单项数据流实例分享
2020/02/16 Javascript
vue数据更新UI不刷新显示的解决办法
2020/08/06 Javascript
[42:35]2018DOTA2亚洲邀请赛3月30日 小组赛A组 VG VS OpTic
2018/03/31 DOTA
[02:18]《我与DAC》之工作人员:为了热爱DOTA2的玩家们
2018/03/28 DOTA
Python中的变量和作用域详解
2016/07/13 Python
基于python读取.mat文件并取出信息
2019/12/16 Python
详解Pycharm与anaconda安装配置指南
2020/08/25 Python
美国男女折扣服饰百货连锁店:Stein Mart
2017/05/02 全球购物
Blank NYC官网:夹克、牛仔裤等
2020/12/16 全球购物
空字符串(“”)和null的区别
2012/11/13 面试题
挑战杯创业计划书的写作指南
2014/01/07 职场文书
2014年法务工作总结
2014/12/11 职场文书
Python还能这么玩之用Python做个小游戏的外挂
2021/06/04 Python
Pygame Time时间控制的具体使用详解
2021/11/17 Python
MySQL分布式恢复进阶
2022/07/23 MySQL