从数据结构的角度分析 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的模拟苹果桌面Dock效果(稳定版)
Oct 15 Javascript
JavaScript中使用Substring删除字符串最后一个字符
Nov 03 Javascript
JS刷新当前页面的几种方法总结
Dec 24 Javascript
jQuery 3.0 的变化及使用方法
Feb 01 Javascript
浅析Javascript中bind()方法的使用与实现
May 30 Javascript
jQuery+正则+文本框只能输入数字的实现方法
Oct 07 Javascript
JavaScript中${pageContext.request.contextPath}取值问题及解决方案
Dec 08 Javascript
jQuery Validate插件自定义验证规则的方法
Dec 27 Javascript
Vuejs实现带样式的单文件组件新方法
May 02 Javascript
jQuery实现下拉菜单的实例代码
Jun 19 jQuery
基于axios 的responseType类型的设置方法
Oct 29 Javascript
微信小程序表单验证WxValidate的使用
Nov 27 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
php强制下载类型的实现代码
2011/04/21 PHP
PHP跨时区(UTC时间)应用解决方案
2013/01/11 PHP
PHP判断变量是否为0的方法
2014/02/08 PHP
PHP同时连接多个mysql数据库示例代码
2014/03/17 PHP
PHP实现获取域名的方法小结
2014/11/05 PHP
php可应用于面包屑导航的迭代寻找家谱树实现方法
2015/02/02 PHP
php导出中文内容excel文件类实例
2015/07/06 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
2018/02/11 PHP
php json转换相关知识(小结)
2018/12/21 PHP
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
2014/02/12 Javascript
jQuery获取和设置表单元素的方法
2014/02/14 Javascript
判断iframe里的页面是否加载完成
2014/06/06 Javascript
深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例
2014/08/04 Javascript
js和jquery设置disabled属性为true使按钮失效
2014/08/07 Javascript
javascript设计模式之中介者模式Mediator
2014/12/30 Javascript
JavaScript头像上传插件源码分享
2016/03/29 Javascript
AngularJS模块详解及示例代码
2016/08/17 Javascript
Vue2.0实现1.0的搜索过滤器功能实例代码
2017/03/20 Javascript
动态创建Angular组件实现popup弹窗功能
2017/09/15 Javascript
vue对storejs获取的数据进行处理时遇到的几种问题小结
2018/03/20 Javascript
JS实现前端动态分页码代码实例
2020/06/02 Javascript
详解JavaScript 事件流
2020/09/02 Javascript
[27:02]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第三场
2014/05/24 DOTA
python实现的简单抽奖系统实例
2015/05/22 Python
在Django的通用视图中处理Context的方法
2015/07/21 Python
Python 中字符串拼接的多种方法
2018/07/30 Python
对python数据切割归并算法的实例讲解
2018/12/12 Python
Python定时任务随机时间执行的实现方法
2019/08/14 Python
KIEHL’S科颜氏官方旗舰店:源自美国的顶级护肤品牌
2018/06/07 全球购物
Glamest意大利:女性在线奢侈品零售店
2019/04/28 全球购物
旅游管理专业生自荐信范文
2014/01/02 职场文书
业务部主管岗位职责
2014/01/29 职场文书
安全教育演讲稿
2014/05/09 职场文书
人与自然观后感
2015/06/16 职场文书
VUE中的v-if与v-show区别介绍
2022/03/13 Vue.js