从数据结构的角度分析 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 相关文章推荐
文字幻灯片
Jun 26 Javascript
MSN消息提示类
Sep 05 Javascript
jQuery 渐变下拉菜单
Dec 15 Javascript
关于 文本框默认值 的操作js代码
Jan 12 Javascript
ajax的hide隐藏问题解决方法
Dec 11 Javascript
Jquery实现带动画效果的经典二级导航菜单
Mar 22 Javascript
jquery实现input输入框实时输入触发事件代码
Jan 28 Javascript
8个超实用的jQuery功能代码分享
Jan 08 Javascript
Javascript中setTimeOut和setInterval的定时器用法
Jun 12 Javascript
jQuery实现微信长按识别二维码功能
Aug 26 Javascript
基于LayUI分页和LayUI laypage分页的使用示例
Aug 02 Javascript
k8s node节点重新加入master集群的实现
Feb 22 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
Codeigniter出现错误提示Error with CACHE directory的解决方案
2014/06/12 PHP
Laravel 实现数据软删除功能
2019/08/21 PHP
PHP基于进程控制函数实现多线程
2020/12/09 PHP
setTimeout与setInterval在不同浏览器下的差异
2010/01/24 Javascript
javascript倒计时功能实现代码
2012/06/07 Javascript
JavaScript实现多维数组的方法
2013/11/20 Javascript
javascript拖拽上传类库DropzoneJS使用方法
2013/12/05 Javascript
javascript实现复选框选中属性
2015/03/25 Javascript
JS+CSS实现下拉列表框美化效果(3款)
2015/08/15 Javascript
JavaScript的this关键字的理解
2016/06/18 Javascript
ES6中Math对象的部分扩展
2017/02/20 Javascript
JS移动端/H5同时选择多张图片上传并使用canvas压缩图片
2017/06/20 Javascript
解决iView中时间控件选择的时间总是少一天的问题
2018/03/15 Javascript
vue弹窗消息组件的使用方法
2020/09/24 Javascript
vue filter 完美时间日期格式的代码
2019/08/14 Javascript
JavaScript实现字符串与HTML格式相互转换
2020/03/17 Javascript
[48:00]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第二场 11.04
2020/11/04 DOTA
[30:55]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第二场 11.18
2020/11/18 DOTA
使用url_helper简化Python中Django框架的url配置教程
2015/05/30 Python
python使用xmlrpclib模块实现对百度google的ping功能
2015/06/02 Python
python自动化实现登录获取图片验证码功能
2019/11/20 Python
python之array赋值技巧分享
2019/11/28 Python
python GUI库图形界面开发之PyQt5滑块条控件QSlider详细使用方法与实例
2020/02/28 Python
浅谈Tensorflow加载Vgg预训练模型的几个注意事项
2020/05/26 Python
浅谈keras中的目标函数和优化函数MSE用法
2020/06/10 Python
Python接口自动化测试框架运行原理及流程
2020/11/30 Python
Python 实现一个简单的web服务器
2021/01/03 Python
HTML5实现WebSocket协议原理浅析
2014/07/07 HTML / CSS
美国轮胎网站:Priority Tire
2018/11/28 全球购物
成功的酒店创业计划书
2013/12/27 职场文书
求职信模板
2014/05/23 职场文书
教育系统干部作风整顿心得体会
2014/09/09 职场文书
2014小学语文教学工作总结
2014/12/17 职场文书
企业投资意向书
2015/05/09 职场文书
Nginx已编译的nginx-添加新模块
2021/04/01 Servers
Python实现byte转integer
2021/06/03 Python