从数据结构分析看:用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 相关文章推荐
jQuery的Ajax时无响应数据的解决方法
May 25 Javascript
jquery 插件开发备注
Aug 27 Javascript
浅析jQuery中调用ajax方法时在不同浏览器中遇到的问题
Jun 11 Javascript
Javascript获取当前时间函数和时间操作小结
Oct 01 Javascript
jquery带动画效果幻灯片特效代码
Aug 27 Javascript
AngularJS 模型详细介绍及实例代码
Jul 27 Javascript
Node.js v8.0.0正式发布!看看带来了哪些主要新特性
Jun 02 Javascript
详解Angular 中 ngOnInit 和 constructor 使用场景
Jun 22 Javascript
ES6中Class类的静态方法实例小结
Oct 28 Javascript
小程序tab页无法传递参数的方法
Aug 03 Javascript
对angular2中的ngfor和ngif指令嵌套实例讲解
Sep 12 Javascript
一篇文章介绍redux、react-redux、redux-saga总结
May 23 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读取文件内容后清空文件示例代码
2014/03/18 PHP
php防止网站被刷新的方法汇总
2014/12/01 PHP
PHP生成json和xml类型接口数据格式
2015/05/17 PHP
PHP实现读取文件夹及批量重命名文件操作示例
2019/04/15 PHP
JavaScript 替换Html标签实现代码
2009/10/14 Javascript
jQuery hover 延时器实现代码
2011/03/12 Javascript
使用js如何实现全选与全不选
2013/12/30 Javascript
javascript计算用户打开网页的停留时间
2014/01/09 Javascript
js读取被点击次数的简单实例(从数据库中读取)
2014/03/07 Javascript
js闭包的用途详解
2014/11/09 Javascript
js检测判断日期大于多少天的方法
2015/05/04 Javascript
浅谈Javascript线程及定时机制
2015/07/02 Javascript
3kb jQuery代码搞定各种树形选择的实现方法
2016/06/10 Javascript
jQuery双向列表选择器DIV模拟版
2016/11/01 Javascript
Vue.js教程之计算属性
2016/11/11 Javascript
jquery与js实现全选功能的区别
2017/06/11 jQuery
XMLHttpRequest对象_Ajax异步请求重点(推荐)
2017/09/28 Javascript
Vue实现类似Spring官网图片滑动效果方法
2019/03/01 Javascript
vue实现文件上传读取及下载功能
2020/11/17 Javascript
Windows上node.js的多版本管理工具用法实例分析
2019/11/06 Javascript
Vue+Element-U实现分页显示效果
2020/11/15 Javascript
python生成器的使用方法
2013/11/21 Python
python实现的一个火车票转让信息采集器
2014/07/09 Python
python 文件操作删除某行的实例
2017/09/04 Python
python实现图像拼接
2020/03/05 Python
美国嘻哈文化生活方式品牌:GLD
2018/04/15 全球购物
英国在线照明超市:Castlegate Lights
2019/10/30 全球购物
2014基层党员干部学习全国两会心得体会
2014/03/17 职场文书
食品采购员岗位职责
2014/04/14 职场文书
节约粮食标语
2014/06/18 职场文书
2014年体育教师工作总结
2014/12/03 职场文书
2015年国庆节活动总结
2015/03/23 职场文书
Python requests库参数提交的注意事项总结
2021/03/29 Python
使用springboot暴露oracle数据接口的问题
2021/05/07 Oracle
Python 用户输入和while循环的操作
2021/05/23 Python
JDK8中String的intern()方法实例详细解读
2022/09/23 Java/Android