从数据结构分析看:用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 相关文章推荐
newxtree.js代码
Mar 13 Javascript
js实现兼容IE6与IE7的DIV高度
May 13 Javascript
JavaScript类和继承 prototype属性
Sep 03 Javascript
改变文件域的样式实现思路同时兼容ie、firefox
Oct 23 Javascript
jquery的ajax简单结构示例代码
Feb 17 Javascript
js实现简单的碰壁反弹效果
Aug 30 Javascript
JS定时器用法分析【时钟与菜单中的应用】
Dec 21 Javascript
JavaScript中的this陷阱的最全收集并整理(没有之一)
Feb 21 Javascript
AngularJS 验证码60秒倒计时功能的实现
Jun 05 Javascript
Vue.js 2.x之组件的定义和注册图文详解
Jun 19 Javascript
微信小程序手机号码验证功能的实例代码
Aug 28 Javascript
react国际化react-intl的使用
May 06 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 基于文件头的文件类型验证类函数
2012/05/01 PHP
php获取url参数方法总结
2014/11/13 PHP
php实现的XML操作(读取)封装类完整实例
2017/02/23 PHP
PHP树形结构tree类用法示例
2019/02/01 PHP
jQuery总体架构的理解分析
2011/03/07 Javascript
js实现的简单radio背景颜色选择器代码
2015/08/18 Javascript
jQuery实现的仿select功能代码
2015/08/19 Javascript
详解JavaScript对象和数组
2015/12/03 Javascript
javascript HTML5 canvas实现打砖块游戏
2020/06/18 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
2016/04/06 Javascript
解析Vue2.0双向绑定实现原理
2017/02/23 Javascript
小程序多图列表实现性能优化的方法步骤
2019/05/28 Javascript
vue使用showdown并实现代码区域高亮的示例代码
2019/10/17 Javascript
js判断密码强度的方法
2020/03/18 Javascript
简单介绍Python的Django框架加载模版的方式
2015/07/20 Python
python实现备份目录的方法
2015/08/03 Python
Python操作MongoDB详解及实例
2017/05/18 Python
python微信跳一跳系列之色块轮廓定位棋盘
2018/02/26 Python
浅析python实现scrapy定时执行爬虫
2018/03/04 Python
Python基础之循环语句用法示例【for、while循环】
2019/03/23 Python
python输入一个水仙花数(三位数) 输出百位十位个位实例
2020/05/03 Python
详解Python利用configparser对配置文件进行读写操作
2020/11/03 Python
CSS3 实现footer 固定在底部(无论页面多高始终在底部)
2019/10/15 HTML / CSS
Marks & Spencer爱尔兰:英国马莎百货
2016/04/20 全球购物
100%植物性、有机、即食餐:Sakara Life
2018/10/25 全球购物
建筑系毕业生自我鉴定
2014/01/24 职场文书
研修心得体会
2014/09/04 职场文书
初级党校心得体会
2014/09/11 职场文书
2014年最新党员对照检查材料汇总
2014/09/15 职场文书
初中信息技术教学计划
2015/01/22 职场文书
资料员岗位职责
2015/02/10 职场文书
优秀员工自荐书
2015/03/06 职场文书
关爱空巢老人感想
2015/08/11 职场文书
golang中字符串MD5生成方式总结
2021/07/04 Golang
redis requires ruby version2.2.2的解决方案
2021/07/15 Redis
Golang bufio详细讲解
2022/04/21 Golang