从数据结构的角度分析 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 相关文章推荐
JS中Iframe之间传值及子页面与父页面应用
Mar 11 Javascript
解决IE6的PNG透明JS插件使用介绍
Apr 17 Javascript
JS批量操作CSS属性详细解析
Dec 16 Javascript
js获取和设置属性的方法
Feb 20 Javascript
jquery实现实时改变网页字体大小、字体背景色和颜色的方法
Aug 05 Javascript
JavaScript实现的经典文件树菜单效果
Sep 08 Javascript
JS实现左右无缝轮播图代码
May 01 Javascript
jQuery实现淡入淡出的模态框
Feb 09 Javascript
javascript简单写的判断电话号码实例
May 24 Javascript
微信小程序使用form表单获取输入框数据的实例代码
May 17 Javascript
js+for循环实现字符串自动转义的代码(把后面的字符替换前面的字符)
Dec 24 Javascript
前端学习——JavaScript原生实现购物车案例
Mar 31 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
Yii快速入门经典教程
2015/12/28 PHP
js 浏览器事件介绍
2012/03/30 Javascript
javascript学习笔记(八) js内置对象
2012/06/19 Javascript
javascript中函数作为参数调用的方法
2015/02/09 Javascript
在JavaScript中处理数组之reverse()方法的使用
2015/06/09 Javascript
JQuery删除DOM节点的方法
2015/06/11 Javascript
Js实现简单的小球运动特效
2016/02/18 Javascript
WebApi+Bootstrap+KnockoutJs打造单页面程序
2016/05/16 Javascript
浅谈javascript中关于日期和时间的基础知识
2016/07/13 Javascript
javascript中异常处理案例(推荐)
2016/10/03 Javascript
微信小程序 less文件编译成wxss文件实现办法
2016/12/05 Javascript
常用JS图片滚动(无缝、平滑、上下左右滚动)代码大全(推荐)
2016/12/20 Javascript
详解bootstrap的modal-remote两种加载方式【强化】
2017/01/27 Javascript
Javascript基础回顾之(一) 类型
2017/01/31 Javascript
JS判断键盘是否按的回车键并触发指定按钮点击操作的方法
2017/02/13 Javascript
vue移动端裁剪图片结合插件Cropper的使用实例代码
2017/07/10 Javascript
vue+ElementUI实现订单页动态添加产品数据效果实例代码
2017/07/13 Javascript
vue-router 导航钩子的具体使用方法
2017/08/31 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
详解Vue CLI3 多页应用实践和源码设计
2018/08/30 Javascript
详解html-webpack-plugin插件(用法总结)
2018/09/12 Javascript
浅谈JS的原型和继承
2019/05/08 Javascript
vue-router 按需加载 component: () => import() 报错的解决
2020/09/22 Javascript
Python程序中使用SQLAlchemy时出现乱码的解决方案
2015/04/24 Python
Python学习之Django的管理界面代码示例
2018/02/10 Python
elasticsearch python 查询的两种方法
2019/08/04 Python
世界上最大的曲棍球商店:Pro Hockey Life
2017/10/30 全球购物
Mio Skincare法国官网:身体紧致及孕期身体护理
2018/04/04 全球购物
香港现代设计家具品牌:Ziinlife Furniture
2018/11/13 全球购物
什么时候需要进行强制类型转换
2016/09/03 面试题
幼儿园教师备课制度
2014/01/12 职场文书
有关爱国演讲稿
2014/05/07 职场文书
关于感恩的演讲稿500字
2014/08/26 职场文书
优秀教师先进事迹材料
2014/12/15 职场文书
小学2016年“我们的节日·重阳节”活动总结
2016/04/01 职场文书
利用Python网络爬虫爬取各大音乐评论的代码
2021/04/13 Python