从数据结构的角度分析 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 相关文章推荐
javascript 操作文件 实现方法小结
Jul 02 Javascript
模仿jQuery each函数的链式调用
Jul 22 Javascript
MooTools 1.2介绍
Sep 14 Javascript
JavaScript中instanceof运算符的用法总结
Nov 19 Javascript
JavaScript参数个数可变的函数举例说明
Oct 10 Javascript
AngularJS实现根据不同条件显示不同控件
Apr 20 Javascript
原生JavaScript实现Ajax异步请求
Nov 19 Javascript
vue中实现图片和文件上传的示例代码
Mar 16 Javascript
vue.js数据绑定操作详解
Apr 23 Javascript
VUE-Table上绑定Input通过render实现双向绑定数据的示例
Aug 27 Javascript
实现一个Vue自定义指令懒加载的方法示例
Jun 04 Javascript
jquery实现简单拖拽效果
Jul 20 jQuery
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自动适应范围的分页代码
2008/08/05 PHP
php算法实例分享
2015/07/14 PHP
详解php的socket通信
2015/08/11 PHP
PHP实现权限管理功能示例
2017/09/22 PHP
推荐10个超棒的jQuery工具提示插件
2011/10/11 Javascript
THREE.JS入门教程(1)THREE.JS使用前了解
2013/01/24 Javascript
extjs 3.31 TreeGrid实现静态页面加载json到TreeGrid里面
2013/04/02 Javascript
javascript表单验证大全
2015/08/12 Javascript
基于jQuery+PHP+Mysql实现在线拍照和在线浏览照片
2015/09/06 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
2016/05/17 Javascript
Javascript中prototype的使用详解
2016/06/18 Javascript
JQuery控制DIV的选取实现方法
2016/09/18 Javascript
jQuery Ajax实现跨域请求
2017/01/21 Javascript
Angular之指令Directive用法详解
2017/03/01 Javascript
在 webpack 中使用 ECharts的实例详解
2018/02/05 Javascript
vue页面离开后执行函数的实例
2018/03/13 Javascript
vue iview多张图片大图预览、缩放翻转
2019/07/13 Javascript
vue使用代理解决请求跨域问题详解
2019/07/24 Javascript
小程序实现图片预览裁剪插件
2019/11/22 Javascript
JavaScript中继承原理与用法实例入门
2020/05/09 Javascript
python每次处理固定个数的字符的方法总结
2013/01/29 Python
Python实现提取文章摘要的方法
2015/04/21 Python
Python_LDA实现方法详解
2017/10/25 Python
Django框架模板语言实例小结【变量,标签,过滤器,继承,html转义】
2019/05/23 Python
在django中,关于session的通用设置方法
2019/08/06 Python
Expedia马来西亚旅游网站:廉价酒店,度假村和航班预订
2016/07/26 全球购物
什么是lambda函数
2013/09/17 面试题
Unix/Linux开发面试题
2016/08/16 面试题
物业管理个人自我评价
2013/11/08 职场文书
迎八一活动主题
2014/01/31 职场文书
机关会计岗位职责
2014/04/08 职场文书
安全责任书范本
2014/04/15 职场文书
幼儿园迎国庆65周年活动策划方案
2014/09/16 职场文书
2015年房产销售工作总结范文
2015/05/22 职场文书
《金色的草地》教学反思
2016/02/17 职场文书
最新动漫情报:2022年7月新番定档超过30部, OVERLORD骨王第四季也在其中噢
2022/05/04 日漫