从数据结构的角度分析 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 相关文章推荐
jQuery 美元符冲突的解决方法
Mar 28 Javascript
JQuery 自定义CircleAnimation,Animate方法学习笔记
Jul 10 Javascript
JavaScript中的console.log()函数详细介绍
Dec 29 Javascript
javascript实现移动端上的触屏拖拽功能
Mar 04 Javascript
第二次聊一聊JS require.js模块化工具的基础知识
Apr 17 Javascript
Angular表单验证实例详解
Oct 20 Javascript
Echarts基本用法_动力节点Java学院整理
Aug 11 Javascript
基于javascript 显式转换与隐式转换(详解)
Dec 15 Javascript
elementui的默认样式修改方法
Feb 23 Javascript
axios全局请求参数设置,请求及返回拦截器的方法
Mar 05 Javascript
CKEditor4配置与开发详细中文说明文档
Oct 08 Javascript
vue刷新页面时去闪烁提升用户体验效果的实现方法
Dec 10 Javascript
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
星际争霸 Starcraft 秘技补丁
2020/03/14 星际争霸
php 移除数组重复元素的一点说明
2008/11/27 PHP
php win下Socket方式发邮件类
2009/08/21 PHP
让的PHP代码飞起来的40条小技巧(提升php效率)
2010/04/12 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
2014/01/03 PHP
php导出csv数据在浏览器中输出提供下载或保存到文件的示例
2014/04/24 PHP
php.ini save_handler 修改不生效的解决办法
2014/07/22 PHP
取得单条网站评论以数组形式进行输出
2014/07/28 PHP
php制作文本式留言板
2015/03/18 PHP
浅析Yii2 GridView实现下拉搜索教程
2016/04/22 PHP
Javascript实现DIV滚动自动滚动到底部的代码
2012/03/01 Javascript
jQuery的cookie插件实现保存用户登陆信息
2014/04/15 Javascript
JS 数字转换为大写金额的简单实例
2016/08/04 Javascript
JS回调函数基本定义与用法实例分析
2017/05/24 Javascript
Webpack性能优化 DLL 用法详解
2017/08/10 Javascript
js模块加载方式浅析
2017/08/12 Javascript
JavaScript时间戳与时间日期间相互转换
2017/12/11 Javascript
vue.js2.0 实现better-scroll的滚动效果实例详解
2018/08/13 Javascript
Vue 配合eiement动态路由,权限验证的方法
2018/09/26 Javascript
vuex如何重置所有state(可定制)
2019/01/17 Javascript
vue下载excel的实现代码后台用post方法
2019/05/10 Javascript
解决layer.confirm选择完之后消息框不消失的问题
2019/09/16 Javascript
[42:32]Secret vs Optic 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python中的字符串替换操作示例
2016/06/27 Python
Python3中的列表,元组,字典,字符串相关知识小结
2017/11/10 Python
Python实现获取邮箱内容并解析的方法示例
2018/06/16 Python
python中PS 图像调整算法原理之亮度调整
2019/06/28 Python
css3实现动画的三种方式
2020/08/24 HTML / CSS
Hobbs官方网站:英国奢华女性时尚服装
2020/02/22 全球购物
科颜氏印度官网:Kiehl’s印度
2021/02/20 全球购物
仙境之桥观后感
2015/06/16 职场文书
三八节活动主持词
2015/07/04 职场文书
企业安全隐患排查治理制度
2015/08/05 职场文书
2016年社区“我们的节日·中秋节”活动总结
2016/04/05 职场文书
Python使用scapy模块发包收包
2021/05/07 Python
JavaScript圣杯布局与双飞翼布局实现案例详解
2022/08/05 Javascript