从数据结构分析看:用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 相关文章推荐
js getElementsByTagName的简写方式
Jun 27 Javascript
JS 实现BASE64_ENCODE和BASE64_DECODE(实例代码)
Nov 13 Javascript
js预加载图片方法汇总
Jun 15 Javascript
JavaScript淡入淡出渐变简单实例
Aug 06 Javascript
再谈javascript常见错误及解决方法
Sep 16 Javascript
微信小程序 后台https域名绑定和免费的https证书申请详解
Nov 10 Javascript
详解基于javascript实现的苹果系统底部菜单
Dec 02 Javascript
jQuery+Ajax实现用户名重名实时检测
Jun 01 jQuery
详解关于JSON.parse()和JSON.stringify()的性能小测试
Mar 14 Javascript
vue 实现input表单元素的disabled示例
Oct 28 Javascript
JS数组方法reverse()用法实例分析
Jan 18 Javascript
原生js实现自定义滚动条组件
Jan 20 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
解析PHP的session过期设置
2013/06/29 PHP
分享一个超好用的php header下载函数
2014/01/31 PHP
php对关联数组循环遍历的实现方法
2015/03/13 PHP
PHP PDOStatement::errorInfo讲解
2019/01/31 PHP
php数组函数array_push()、array_pop()及array_shift()简单用法示例
2020/01/26 PHP
JS backgroundImage控制
2009/05/19 Javascript
js 小数取整的函数
2010/05/10 Javascript
Jquery升级新版本后选择器的语法问题
2010/06/02 Javascript
JavaScript接口实现代码 (Interfaces In JavaScript)
2010/06/11 Javascript
拖动布局之保存布局页面cookies篇
2010/10/29 Javascript
jQuery实现form表单reset按钮重置清空表单功能
2012/12/18 Javascript
web的各种前端打印方法之jquery打印插件jqprint实现网页打印
2013/01/09 Javascript
javascript显示用户停留时间的简单实例
2013/08/05 Javascript
js+html5实现可在手机上玩的拼图游戏
2015/07/17 Javascript
js简单判断移动端系统的方法
2016/02/25 Javascript
微信小程序  action-sheet详解及实例代码
2016/11/09 Javascript
浅谈MVC+EF easyui dataGrid 动态加载分页表格
2016/11/10 Javascript
Javascrip实现文字跳动特效
2016/11/27 Javascript
EasyUI Combobox设置默认值 获取text的方法
2016/11/28 Javascript
js实现3D图片展示效果
2017/03/09 Javascript
jQuery Ajax前后端使用JSON进行交互示例
2017/03/17 Javascript
基于Angular中ng-controller父子级嵌套的相关属性详解
2018/10/08 Javascript
[01:49]一目了然!DOTA2DotA快捷操作对比第二弹
2014/05/16 DOTA
Python3实现转换Image图片格式
2018/06/21 Python
python3实现斐波那契数列(4种方法)
2019/07/15 Python
提升python处理速度原理及方法实例
2019/12/25 Python
python在一个范围内取随机数的简单实例
2020/08/16 Python
专门出售各种儿童读物的网站:Put Me In The Story
2016/08/07 全球购物
英国领先的葡萄酒专家:Majestic Wine
2017/05/30 全球购物
杰夫·班克斯男士服装网上商店:Jeff Banks
2019/10/24 全球购物
金融专业大学生职业生涯规划范文
2014/01/16 职场文书
2014年信访维稳工作总结
2014/12/08 职场文书
学校扫黄打非工作总结
2015/10/15 职场文书
关于感恩的作文
2019/08/26 职场文书
导游词之河北白洋淀
2020/01/15 职场文书
go select编译期的优化处理逻辑使用场景分析
2021/06/28 Golang