从数据结构的角度分析 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编程起步(第二课)
Feb 27 Javascript
JavaScript高级程序设计 扩展--关于动态原型
Nov 09 Javascript
js给onclick事件赋值,动态传参数实例解说
Mar 28 Javascript
js查找某元素中的所有图片地址的方法
Jan 16 Javascript
JavaScript数组深拷贝和浅拷贝的两种方法
Apr 16 Javascript
在JavaScript中用getMinutes()方法返回指定的分时刻
Jun 10 Javascript
JavaScript基础篇(3)之Object、Function等引用类型
Nov 30 Javascript
关于angular js_$watch监控属性和对象详解
Apr 24 Javascript
Angular2学习教程之组件中的DOM操作详解
May 28 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
Sep 19 Javascript
微信小程序实现时间戳格式转换
Jul 20 Javascript
vue穿梭框实现上下移动
Jan 29 Vue.js
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
建立动态的WML站点(二)
2006/10/09 PHP
yii实现图片上传及缩略图生成的方法
2014/12/04 PHP
PHP编程实现脚本异步执行的方法
2017/08/09 PHP
PHP实现简单用户登录界面
2019/10/23 PHP
dotopAlert 提示用户需安装播放器的代码
2012/09/17 Javascript
JQuery删除DOM节点的方法
2015/06/11 Javascript
js实现浏览本地文件并显示扩展名的方法
2015/08/17 Javascript
浅谈javascript 函数表达式和函数声明的区别
2016/01/05 Javascript
vue+vuex+axios实现登录、注册页权限拦截
2018/03/09 Javascript
详解react、redux、react-redux之间的关系
2018/04/11 Javascript
VeeValidate在vue项目里表单校验应用案例
2018/05/09 Javascript
JS数组中对象去重操作示例
2019/06/04 Javascript
uploadify插件实现多个图片上传并预览
2019/09/30 Javascript
jquery实现上传文件进度条
2020/03/26 jQuery
python和pyqt实现360的CLable控件
2014/02/21 Python
Python文件去除注释的方法
2015/05/25 Python
Python中特殊函数集锦
2015/07/27 Python
Python基于分水岭算法解决走迷宫游戏示例
2017/09/26 Python
python list是否包含另一个list所有元素的实例
2018/05/04 Python
在pycharm上mongodb配置及可视化设置方法
2018/11/30 Python
Python跳出多重循环的方法示例
2019/07/03 Python
Django 全局的static和templates的使用详解
2019/07/19 Python
python批量修改ssh密码的实现
2019/08/08 Python
Python StringIO如何在内存中读写str
2020/01/07 Python
Python脚本如何在bilibili中查找弹幕发送者
2020/06/04 Python
Python过滤序列元素的方法
2020/07/31 Python
CSS3的first-child选择器实战攻略
2016/04/28 HTML / CSS
一套Java笔试题
2016/08/20 面试题
在C语言中实现抽象数据类型什么方法最好
2014/06/26 面试题
专科毕业生就业推荐信
2013/11/01 职场文书
安全教育心得体会
2013/12/29 职场文书
大学生演讲稿范文
2014/01/11 职场文书
小学生成长感言
2014/01/30 职场文书
校园广播稿100字
2014/10/06 职场文书
统计工作个人总结
2015/03/03 职场文书
MySQL聚簇索引和非聚簇索引的区别详情
2022/06/14 MySQL