从数据结构分析看:用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宝典学习笔记
Feb 07 Javascript
如何在Web页面上直接打开、编辑、创建Office文档
Mar 12 Javascript
获取HTML DOM节点元素的方法的总结
Aug 21 Javascript
js返回上一页并刷新代码整理
Dec 21 Javascript
javascript实现密码验证
Nov 10 Javascript
javascript中eval解析JSON字符串
Feb 27 Javascript
轮播的简单实现方法
Jul 28 Javascript
easyui取消表单实时验证,提交时统一验证的简单实例
Nov 07 Javascript
js实现倒计时及时间对象
Nov 15 Javascript
移动端基础事件总结与应用
Jan 12 Javascript
Angular2整合其他插件的方法
Jan 20 Javascript
原生JS+HTML5实现的可调节写字板功能示例
Aug 30 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同时支持GIF、png、JPEG
2006/10/09 PHP
PHP学习笔记 (1) 环境配置与代码调试
2011/06/19 PHP
php 目录与文件处理-郑阿奇(续)
2011/07/04 PHP
php正则表达式使用的详细介绍
2013/04/27 PHP
extjs DataReader、JsonReader、XmlReader的构造方法
2009/11/07 Javascript
JavaScript的React Web库的理念剖析及基础上手指南
2016/05/10 Javascript
浅谈React 属性和状态的一些总结
2016/11/21 Javascript
JS匿名函数类生成方式实例分析
2016/11/26 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
2017/01/11 Javascript
Javascript实现基本运算器
2017/07/15 Javascript
详解在vue-cli中使用路由
2017/09/25 Javascript
vue轮播图插件vue-awesome-swiper
2017/11/27 Javascript
React手稿之 React-Saga的详解
2018/11/12 Javascript
详解基于vue-cli3快速发布一个fullpage组件
2019/03/08 Javascript
js/jQuery实现全选效果
2019/06/17 jQuery
微信小程序request请求封装,验签代码实例
2019/12/04 Javascript
JS前端广告拦截实现原理解析
2020/02/17 Javascript
[01:29:42]Liquid vs VP Supermajor决赛 BO 第一场 6.10
2018/07/05 DOTA
Python中的二叉树查找算法模块使用指南
2014/07/04 Python
九步学会Python装饰器
2015/05/09 Python
Python矩阵常见运算操作实例总结
2017/09/29 Python
python使用json序列化datetime类型实例解析
2018/02/11 Python
40行Python代码实现天气预报和每日鸡汤推送功能
2020/02/27 Python
python字符串常用方法及文件简单读写的操作方法
2020/03/04 Python
pyCharm 设置调试输出窗口中文显示方式(字符码转换)
2020/06/09 Python
使用Keras实现Tensor的相乘和相加代码
2020/06/18 Python
python中plt.imshow与cv2.imshow显示颜色问题
2020/07/16 Python
python 实现朴素贝叶斯算法的示例
2020/09/30 Python
canvas烟花特效锦集
2018/01/17 HTML / CSS
一道Delphi上机题
2012/06/04 面试题
thinkphp5 redis缓存新增方法实例讲解
2021/03/24 PHP
奥利奥广告词
2014/03/20 职场文书
高中生自我评价范文2015
2015/03/03 职场文书
python数据分析之用sklearn预测糖尿病
2021/04/22 Python
在Spring-Boot中如何使用@Value注解注入集合类
2021/08/02 Java/Android
CSS三大特性继承性、层叠性和优先级详解
2022/01/18 HTML / CSS